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
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
2018-05-13 20:49:11 +00:00
* Copyright ( C ) 2010 - 2018 ( 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
2014-12-21 21:46:57 +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
2018-05-13 20:49:11 +00:00
* along with GNSS - SDR . If not , see < https : //www.gnu.org/licenses/>.
2011-10-01 18:45:20 +00:00
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
# include "control_thread.h"
2019-07-17 13:56:30 +00:00
# include "channel_event.h"
# include "command_event.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
# 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
# include <ctime> // for gmtime, strftime
# include <exception> // for exception
# include <iostream> // for operator<<, endl
# 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
2014-01-12 20:07:38 +00:00
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 ) ;
}
2015-05-13 21:26:44 +00:00
delete_configuration_ = false ;
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
2014-04-03 21:59:14 +00:00
ControlThread : : ControlThread ( std : : shared_ptr < ConfigurationInterface > configuration )
2011-10-01 18:45:20 +00:00
{
2019-02-05 00:31:09 +00:00
configuration_ = std : : move ( configuration ) ;
2015-05-13 21:26:44 +00:00
delete_configuration_ = false ;
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 ( )
{
// 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 > > ( ) ;
2018-11-23 15:38:20 +00:00
cmd_interface_ . set_msg_queue ( control_queue_ ) ; //set also the queue pointer for the telecommand thread
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 ( ) < < std : : endl ;
}
stop_ = false ;
processed_control_messages_ = 0 ;
applied_actions_ = 0 ;
supl_mcc = 0 ;
supl_mns = 0 ;
supl_lac = 0 ;
supl_ci = 0 ;
msqid = - 1 ;
agnss_ref_location_ = Agnss_Ref_Location ( ) ;
agnss_ref_time_ = Agnss_Ref_Time ( ) ;
std : : string empty_string = " " ;
std : : string ref_location_str = configuration_ - > property ( " GNSS-SDR.AGNSS_ref_location " , empty_string ) ;
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
{
std : : cerr < < " GNSS-SDR.AGNSS_ref_location= " < < ref_location_str < < " is not a valid position. " < < std : : endl ;
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 ) ;
agnss_ref_time_ . d_tv_sec = rawtime ;
agnss_ref_time_ . valid = true ;
}
else
{
// fill agnss_ref_time_
2018-12-03 09:05:47 +00:00
struct tm tm = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , nullptr } ;
2018-11-23 15:38:20 +00:00
if ( strptime ( ref_time_str . c_str ( ) , " %d/%m/%Y %H:%M:%S " , & tm ) ! = nullptr )
{
agnss_ref_time_ . d_tv_sec = timegm ( & tm ) ;
if ( agnss_ref_time_ . d_tv_sec > 0 )
{
agnss_ref_time_ . valid = true ;
}
else
{
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 " < < std : : endl ;
}
}
else
{
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 " < < std : : endl ;
2018-11-24 08:40:15 +00:00
agnss_ref_time_ . valid = 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
{
2019-02-11 20:13:02 +00:00
if ( msqid ! = - 1 )
{
msgctl ( msqid , IPC_RMID , nullptr ) ;
}
2019-02-24 12:22:52 +00:00
if ( sysv_queue_thread_ . joinable ( ) )
{
sysv_queue_thread_ . join ( ) ;
}
if ( cmd_interface_thread_ . joinable ( ) )
{
2019-02-24 19:57:51 +00:00
cmd_interface_thread_ . detach ( ) ;
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 ( )
{
2018-12-11 09:36:15 +00:00
bool telecommand_enabled = configuration_ - > property ( " GNSS-SDR.telecommand_enabled " , false ) ;
if ( telecommand_enabled )
{
int tcp_cmd_port = configuration_ - > property ( " GNSS-SDR.telecommand_tcp_port " , 3333 ) ;
cmd_interface_ . run_cmd_server ( tcp_cmd_port ) ;
}
2018-10-19 12:54:03 +00:00
}
2018-11-08 14:34:58 +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
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
{
2014-03-16 19:58:29 +00:00
LOG ( ERROR ) < < " Unable to connect flowgraph " ;
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
{
2014-03-16 19:58:29 +00:00
LOG ( ERROR ) < < " Unable to start flowgraph " ;
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
2019-02-24 12:22:52 +00:00
keyboard_thread_ = std : : thread ( & ControlThread : : keyboard_listener , this ) ;
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-16 15:41:12 +00:00
//TODO call here the new sat dispatcher and receiver controller
2019-07-17 13:56:30 +00:00
bool valid_event = control_queue_ - > timed_wait_and_pop ( msg , 100 ) ;
if ( valid_event )
{
if ( pmt : : any_ref ( msg ) . type ( ) = = typeid ( channel_event_sptr ) )
{
channel_event_sptr new_event ;
new_event = boost : : any_cast < channel_event_sptr > ( pmt : : any_ref ( msg ) ) ;
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 ) ;
}
else if ( pmt : : any_ref ( msg ) . type ( ) = = typeid ( command_event_sptr ) )
{
command_event_sptr new_event ;
new_event = boost : : any_cast < command_event_sptr > ( pmt : : any_ref ( msg ) ) ;
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
{
}
2011-12-28 21:36:45 +00:00
}
2013-11-17 10:48:27 +00:00
std : : cout < < " Stopping GNSS-SDR, please wait! " < < std : : endl ;
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-28 08:33:47 +00:00
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( 500 ) ) ;
2019-02-24 12:22:52 +00:00
// Terminate keyboard thread
pthread_t id = keyboard_thread_ . native_handle ( ) ;
keyboard_thread_ . detach ( ) ;
pthread_cancel ( id ) ;
2018-10-23 14:54:06 +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
2019-07-16 15:41:12 +00:00
void ControlThread : : set_control_queue ( const std : : shared_ptr < Concurrent_Queue < pmt : : pmt_t > > control_queue ) // NOLINT(performance-unnecessary-value-param)
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 ;
}
2019-02-05 00:31:09 +00:00
control_queue_ = 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
std : : string eph_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_ephemeris_xml " , eph_default_xml_filename ) ;
2018-10-21 16:27:23 +00:00
std : : string utc_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_utc_model_xml " , utc_default_xml_filename ) ;
2016-04-13 14:19:15 +00:00
std : : string iono_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_iono_xml " , iono_default_xml_filename ) ;
2018-10-18 13:46:48 +00:00
std : : string gal_iono_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gal_iono_xml " , gal_iono_default_xml_filename ) ;
2016-04-13 14:19:15 +00:00
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 ) ;
2018-10-17 17:17:37 +00:00
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 ) ;
2018-10-21 16:27:23 +00:00
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 ) ;
2018-10-20 17:30:32 +00:00
std : : string eph_glo_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_glo_ephemeris_xml " , eph_glo_gnav_default_xml_filename ) ;
2018-10-21 16:27:23 +00:00
std : : string glo_utc_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_glo_utc_model_xml " , glo_utc_default_xml_filename ) ;
2018-11-10 18:16:13 +00:00
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 )
{
eph_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gps_ephemeris_xml " , eph_default_xml_filename ) ;
2018-10-21 16:27:23 +00:00
utc_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_gps_utc_model_xml " , utc_default_xml_filename ) ;
2018-10-21 11:58:29 +00:00
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 ) ;
2018-10-21 16:27:23 +00:00
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 ) ;
2018-10-21 11:58:29 +00:00
eph_glo_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_glo_ephemeris_xml " , eph_glo_gnav_default_xml_filename ) ;
2018-10-21 16:27:23 +00:00
glo_utc_xml_filename = configuration_ - > property ( " GNSS-SDR.AGNSS_glo_utc_model_xml " , glo_utc_default_xml_filename ) ;
2018-11-10 18:16:13 +00:00
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
2018-10-20 12:46:55 +00:00
std : : cout < < " Trying to read GNSS ephemeris from XML file(s)... " < < std : : endl ;
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 + + )
{
std : : cout < < " From XML file: Read NAV ephemeris for satellite " < < Gnss_Satellite ( " GPS " , gps_eph_iter - > second . i_satellite_PRN ) < < std : : endl ;
std : : shared_ptr < Gps_Ephemeris > tmp_obj = std : : make_shared < Gps_Ephemeris > ( gps_eph_iter - > second ) ;
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
{
2018-10-20 12:46:55 +00:00
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 ) ) ;
2018-10-21 15:55:06 +00:00
std : : cout < < " From XML file: Read GPS UTC model parameters. " < < std : : endl ;
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
{
2018-10-20 12:46:55 +00:00
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 ) ) ;
2018-10-21 15:55:06 +00:00
std : : cout < < " From XML file: Read GPS ionosphere model parameters. " < < std : : endl ;
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 + + )
{
std : : cout < < " From XML file: Read GPS almanac for satellite " < < Gnss_Satellite ( " GPS " , gps_alm_iter - > second . i_satellite_PRN ) < < std : : endl ;
std : : shared_ptr < Gps_Almanac > tmp_obj = std : : make_shared < Gps_Almanac > ( gps_alm_iter - > second ) ;
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 + + )
{
std : : cout < < " From XML file: Read ephemeris for satellite " < < Gnss_Satellite ( " Galileo " , gal_eph_iter - > second . i_satellite_PRN ) < < std : : endl ;
std : : shared_ptr < Galileo_Ephemeris > tmp_obj = std : : make_shared < Galileo_Ephemeris > ( gal_eph_iter - > second ) ;
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 )
{
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 ) ) ;
2018-10-21 15:55:06 +00:00
std : : cout < < " From XML file: Read Galileo ionosphere model parameters. " < < std : : endl ;
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 )
{
std : : shared_ptr < Galileo_Utc_Model > tmp_obj = std : : make_shared < Galileo_Utc_Model > ( supl_client_acquisition_ . gal_utc ) ;
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2018-10-21 15:55:06 +00:00
std : : cout < < " From XML file: Read Galileo UTC model parameters. " < < std : : endl ;
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 + + )
{
std : : cout < < " From XML file: Read Galileo almanac for satellite " < < Gnss_Satellite ( " Galileo " , gal_alm_iter - > second . i_satellite_PRN ) < < std : : endl ;
std : : shared_ptr < Galileo_Almanac > tmp_obj = std : : make_shared < Galileo_Almanac > ( gal_alm_iter - > second ) ;
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 + + )
{
std : : cout < < " From XML file: Read CNAV ephemeris for satellite " < < Gnss_Satellite ( " GPS " , gps_cnav_eph_iter - > second . i_satellite_PRN ) < < std : : endl ;
std : : shared_ptr < Gps_CNAV_Ephemeris > tmp_obj = std : : make_shared < Gps_CNAV_Ephemeris > ( gps_cnav_eph_iter - > second ) ;
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 )
{
std : : shared_ptr < Gps_CNAV_Utc_Model > tmp_obj = std : : make_shared < Gps_CNAV_Utc_Model > ( supl_client_acquisition_ . gps_cnav_utc ) ;
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2018-10-21 15:55:06 +00:00
std : : cout < < " From XML file: Read GPS CNAV UTC model parameters. " < < std : : endl ;
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 + + )
{
std : : cout < < " From XML file: Read GLONASS GNAV ephemeris for satellite " < < Gnss_Satellite ( " GLONASS " , glo_gnav_eph_iter - > second . i_satellite_PRN ) < < std : : endl ;
std : : shared_ptr < Glonass_Gnav_Ephemeris > tmp_obj = std : : make_shared < Glonass_Gnav_Ephemeris > ( glo_gnav_eph_iter - > second ) ;
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 )
{
std : : shared_ptr < Glonass_Gnav_Utc_Model > tmp_obj = std : : make_shared < Glonass_Gnav_Utc_Model > ( supl_client_acquisition_ . glo_gnav_utc ) ;
flowgraph_ - > send_telemetry_msg ( pmt : : make_any ( tmp_obj ) ) ;
2018-10-21 15:55:06 +00:00
std : : cout < < " From XML file: Read GLONASS UTC model parameters. " < < std : : endl ;
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
{
2018-10-21 11:58:29 +00:00
std : : cout < < " Error reading XML files " < < std : : endl ;
std : : cout < < " Disabling GNSS assistance... " < < std : : endl ;
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
2016-04-13 14:19:15 +00:00
bool enable_gps_supl_assistance = configuration_ - > property ( " GNSS-SDR.SUPL_gps_enabled " , false ) ;
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 " ;
2018-11-20 08:28:47 +00:00
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 " ;
2018-11-20 08:28:47 +00:00
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
{
2013-11-17 10:48:27 +00:00
//######### GNSS Assistance #################################
// GNSS Assistance configuration
bool enable_gps_supl_assistance = configuration_ - > property ( " GNSS-SDR.SUPL_gps_enabled " , false ) ;
2018-10-21 15:55:06 +00:00
bool enable_agnss_xml = configuration_ - > property ( " GNSS-SDR.AGNSS_XML_enabled " , false ) ;
if ( ( enable_gps_supl_assistance = = true ) and ( enable_agnss_xml = = false ) )
2013-11-17 10:48:27 +00:00
{
std : : cout < < " SUPL RRLP GPS assistance enabled! " < < std : : endl ;
2018-10-21 11:58:29 +00:00
std : : string default_acq_server = " supl.google.com " ;
2013-11-17 10:48:27 +00:00
std : : string default_eph_server = " supl.google.com " ;
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 ) ;
supl_mcc = configuration_ - > property ( " GNSS-SDR.SUPL_MCC " , 244 ) ;
2018-10-22 22:16:36 +00:00
supl_mns = configuration_ - > property ( " GNSS-SDR.SUPL_MNC " , 5 ) ;
2013-11-17 10:48:27 +00:00
std : : string default_lac = " 0x59e2 " ;
std : : string default_ci = " 0x31b0 " ;
2018-10-22 12:56:02 +00:00
std : : string supl_lac_s = configuration_ - > property ( " GNSS-SDR.SUPL_LAC " , default_lac ) ;
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
{
2018-10-22 12:56:02 +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 ' ;
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
{
2018-10-22 12:56:02 +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 ' ;
supl_ci = - 1 ;
}
if ( supl_lac < 0 or supl_lac > 65535 )
{
supl_lac = 0x59e2 ;
}
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
{
2013-11-17 10:48:27 +00:00
supl_ci = 0x31b0 ;
2018-03-03 01:03:39 +00:00
}
2013-11-17 10:48:27 +00:00
bool SUPL_read_gps_assistance_xml = configuration_ - > property ( " GNSS-SDR.SUPL_read_gps_assistance_xml " , false ) ;
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 ( ) )
{
2018-10-18 07:29:21 +00:00
std : : cout < < " GNSS assistance data loaded from local XML file(s). " < < std : : endl ;
2018-10-21 15:55:06 +00:00
std : : cout < < " No SUPL request has been performed. " < < std : : endl ;
2016-05-04 17:15:18 +00:00
}
2013-11-17 10:48:27 +00:00
}
else
{
// Request ephemeris from SUPL server
int error ;
supl_client_ephemeris_ . request = 1 ;
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Try to read GPS ephemeris data from SUPL server... " < < std : : endl ;
2013-11-17 10:48:27 +00:00
error = supl_client_ephemeris_ . get_assistance ( supl_mcc , supl_mns , supl_lac , supl_ci ) ;
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
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Received ephemeris data for satellite " < < Gnss_Satellite ( " GPS " , gps_eph_iter - > second . i_satellite_PRN ) < < std : : endl ;
2016-05-04 17:15:18 +00:00
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
2014-04-28 14:27:47 +00:00
std : : string eph_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_ephemeris_xml " , eph_default_xml_filename ) ;
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
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: XML ephemeris data file created " < < std : : endl ;
2013-11-17 10:48:27 +00:00
}
2014-04-28 14:27:47 +00:00
else
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Failed to create XML ephemeris data file " < < std : : endl ;
2014-04-28 14:27:47 +00:00
}
2013-11-17 10:48:27 +00:00
}
else
{
2018-10-21 15:55:06 +00:00
std : : cout < < " ERROR: SUPL client request for ephemeris data returned " < < error < < std : : endl ;
std : : cout < < " Please check your network connectivity and SUPL server configuration " < < std : : endl ;
std : : cout < < " Trying to read AGNSS data from local XML file(s)... " < < std : : endl ;
2016-05-03 10:34:38 +00:00
if ( read_assistance_from_XML ( ) = = false )
{
2018-10-21 15:55:06 +00:00
std : : cout < < " ERROR: Could not read XML files: Disabling SUPL assistance. " < < std : : endl ;
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 ;
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Try to read Almanac, Iono, Utc Model, Ref Time and Ref Location data from SUPL server... " < < std : : endl ;
2013-11-17 10:48:27 +00:00
error = supl_client_ephemeris_ . get_assistance ( supl_mcc , supl_mns , supl_lac , supl_ci ) ;
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
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Received almanac data for satellite " < < Gnss_Satellite ( " GPS " , gps_alm_iter - > second . i_satellite_PRN ) < < std : : endl ;
2016-05-04 17:15:18 +00:00
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 )
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Received GPS Ionosphere model parameters " < < std : : endl ;
2016-05-04 17:15:18 +00:00
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
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Received GPS UTC model parameters " < < std : : endl ;
2016-05-04 17:15:18 +00:00
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
std : : string iono_xml_filename = configuration_ - > property ( " GNSS-SDR.SUPL_gps_iono_xml " , iono_default_xml_filename ) ;
if ( supl_client_ephemeris_ . save_iono_xml ( iono_xml_filename , supl_client_ephemeris_ . gps_iono ) = = true )
{
std : : cout < < " SUPL: Iono data file created " < < std : : endl ;
}
else
{
std : : cout < < " SUPL: Failed to create Iono data file " < < std : : endl ;
}
2018-10-21 16:27:23 +00:00
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 )
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: UTC model data file created " < < std : : endl ;
2018-10-21 11:58:29 +00:00
}
else
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Failed to create UTC model data file " < < std : : endl ;
2018-10-21 11:58:29 +00:00
}
2013-11-17 10:48:27 +00:00
}
else
{
2018-10-21 15:55:06 +00:00
std : : cout < < " ERROR: SUPL client for almanac data returned " < < error < < std : : endl ;
std : : cout < < " Please check your network connectivity and SUPL server configuration " < < std : : endl ;
2013-11-17 10:48:27 +00:00
}
// Request acquisition assistance
supl_client_acquisition_ . request = 2 ;
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Try to read acquisition assistance data from SUPL server... " < < std : : endl ;
2013-11-17 10:48:27 +00:00
error = supl_client_acquisition_ . get_assistance ( supl_mcc , supl_mns , supl_lac , supl_ci ) ;
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
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Received acquisition assistance data for satellite " < < Gnss_Satellite ( " GPS " , gps_acq_iter - > second . i_satellite_PRN ) < < std : : endl ;
2014-05-13 12:58:03 +00:00
global_gps_acq_assist_map . write ( gps_acq_iter - > second . i_satellite_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 )
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Received Ref Location data (Acquisition Assistance) " < < std : : endl ;
2018-11-20 08:28:47 +00:00
agnss_ref_location_ = supl_client_acquisition_ . gps_ref_loc ;
2018-11-20 11:46:38 +00:00
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 )
{
2018-10-21 15:55:06 +00:00
std : : cout < < " SUPL: Received Ref Time data (Acquisition Assistance) " < < std : : endl ;
2018-11-20 08:28:47 +00:00
agnss_ref_time_ = supl_client_acquisition_ . gps_time ;
2018-11-20 11:46:38 +00:00
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
{
2018-10-21 15:55:06 +00:00
std : : cout < < " ERROR: SUPL client for acquisition assistance returned " < < error < < std : : endl ;
std : : cout < < " Please check your network connectivity and SUPL server configuration " < < std : : endl ;
std : : cout < < " Disabling SUPL acquisition assistance. " < < std : : endl ;
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 ( ) )
{
std : : cout < < " GNSS assistance data loaded from local XML file(s). " < < std : : endl ;
}
}
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
2018-11-20 11:46:38 +00:00
arma : : vec ref_LLH = arma : : zeros ( 3 , 1 ) ;
2018-11-20 08:28:47 +00:00
ref_LLH ( 0 ) = agnss_ref_location_ . lat ;
ref_LLH ( 1 ) = agnss_ref_location_ . lon ;
time_t ref_rx_utc_time = 0 ;
2018-11-20 11:46:38 +00:00
if ( agnss_ref_time_ . valid = = true )
{
2018-12-14 13:17:04 +00:00
ref_rx_utc_time = static_cast < time_t > ( agnss_ref_time_ . d_tv_sec ) ;
2018-11-20 11:46:38 +00:00
}
2018-11-20 08:28:47 +00:00
std : : vector < std : : pair < int , Gnss_Satellite > > visible_sats = get_visible_sats ( ref_rx_utc_time , ref_LLH ) ;
// 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
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 ;
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 ;
applied_actions_ + + ;
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 ;
applied_actions_ + + ;
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
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 ) ;
2018-11-24 08:40:15 +00:00
// start again the satellite acquisitions (done in chained apply_action to flowgraph)
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 ) ;
2018-11-24 08:40:15 +00:00
// start again the satellite acquisitions (done in chained apply_action to flowgraph)
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
std : : vector < std : : pair < int , Gnss_Satellite > > ControlThread : : get_visible_sats ( time_t rx_utc_time , const arma : : vec & 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
2018-11-05 16:53:53 +00:00
arma : : vec LLH_rad = arma : : vec { degtorad ( LLH ( 0 ) ) , degtorad ( LLH ( 1 ) ) , LLH ( 2 ) } ;
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 ;
2018-11-05 16:53:53 +00:00
gtime_t gps_gtime = utc2gpst ( utc_gtime ) ;
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 ;
2018-11-05 16:53:53 +00:00
std : : shared_ptr < PvtInterface > pvt_ptr = flowgraph_ - > get_pvt ( ) ;
2018-12-03 09:05:47 +00:00
struct tm tstruct = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , nullptr } ;
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 ) ;
std : : string str_time = std : : string ( buf ) ;
std : : cout < < " Get visible satellites at " < < str_time
2018-11-22 16:07:01 +00:00
< < " UTC, assuming RX position " < < LLH ( 0 ) < < " [deg], " < < LLH ( 1 ) < < " [deg], " < < LLH ( 2 ) < < " [m] " < < std : : endl ;
2018-11-05 16:53:53 +00:00
std : : map < int , Gps_Ephemeris > gps_eph_map = pvt_ptr - > get_gps_ephemeris ( ) ;
2019-02-10 13:07:27 +00:00
for ( auto & it : gps_eph_map )
2018-11-05 16:53:53 +00:00
{
2019-02-05 00:31:09 +00:00
eph_t rtklib_eph = eph_to_rtklib ( it . second ) ;
2018-11-05 16:53:53 +00:00
double r_sat [ 3 ] ;
double clock_bias_s ;
double sat_pos_variance_m2 ;
eph2pos ( gps_gtime , & rtklib_eph , & r_sat [ 0 ] , & clock_bias_s ,
& sat_pos_variance_m2 ) ;
double Az , El , dist_m ;
arma : : vec r_sat_eb_e = arma : : vec { r_sat [ 0 ] , r_sat [ 1 ] , r_sat [ 2 ] } ;
arma : : vec dx = r_sat_eb_e - r_eb_e ;
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 )
{
2019-02-05 00:31:09 +00:00
std : : cout < < " Using GPS Ephemeris: Sat " < < it . second . i_satellite_PRN < < " Az: " < < Az < < " El: " < < El < < std : : endl ;
2019-06-29 22:01:54 +00:00
available_satellites . emplace_back ( floor ( El ) ,
( Gnss_Satellite ( std : : string ( " GPS " ) , it . second . i_satellite_PRN ) ) ) ;
2019-02-05 00:31:09 +00:00
visible_gps . push_back ( it . second . i_satellite_PRN ) ;
2018-11-05 16:53:53 +00:00
}
}
std : : map < int , Galileo_Ephemeris > gal_eph_map = pvt_ptr - > get_galileo_ephemeris ( ) ;
2019-02-10 13:07:27 +00:00
for ( auto & it : gal_eph_map )
2018-11-05 16:53:53 +00:00
{
2019-02-05 00:31:09 +00:00
eph_t rtklib_eph = eph_to_rtklib ( it . second ) ;
2018-11-05 16:53:53 +00:00
double r_sat [ 3 ] ;
double clock_bias_s ;
double sat_pos_variance_m2 ;
eph2pos ( gps_gtime , & rtklib_eph , & r_sat [ 0 ] , & clock_bias_s ,
& sat_pos_variance_m2 ) ;
double Az , El , dist_m ;
arma : : vec r_sat_eb_e = arma : : vec { r_sat [ 0 ] , r_sat [ 1 ] , r_sat [ 2 ] } ;
arma : : vec dx = r_sat_eb_e - r_eb_e ;
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 )
{
2019-02-05 00:31:09 +00:00
std : : cout < < " Using Galileo Ephemeris: Sat " < < it . second . i_satellite_PRN < < " Az: " < < Az < < " El: " < < El < < std : : endl ;
2019-06-29 22:01:54 +00:00
available_satellites . emplace_back ( floor ( El ) ,
( Gnss_Satellite ( std : : string ( " Galileo " ) , it . second . i_satellite_PRN ) ) ) ;
2019-02-05 00:31:09 +00:00
visible_gal . push_back ( it . second . i_satellite_PRN ) ;
2018-11-05 16:53:53 +00:00
}
}
std : : map < int , Gps_Almanac > gps_alm_map = pvt_ptr - > get_gps_almanac ( ) ;
2019-02-10 13:07:27 +00:00
for ( auto & it : gps_alm_map )
2018-11-05 16:53:53 +00:00
{
2019-02-05 00:31:09 +00:00
alm_t rtklib_alm = alm_to_rtklib ( it . second ) ;
2018-11-05 16:53:53 +00:00
double r_sat [ 3 ] ;
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 ;
2018-11-22 16:07:01 +00:00
alm2pos ( aux_gtime , & rtklib_alm , & r_sat [ 0 ] , & clock_bias_s ) ;
2018-11-05 16:53:53 +00:00
double Az , El , dist_m ;
arma : : vec r_sat_eb_e = arma : : vec { r_sat [ 0 ] , r_sat [ 1 ] , r_sat [ 2 ] } ;
arma : : vec dx = r_sat_eb_e - r_eb_e ;
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 )
{
2019-02-05 00:31:09 +00:00
it2 = std : : find ( visible_gps . begin ( ) , visible_gps . end ( ) , it . second . i_satellite_PRN ) ;
2018-11-22 14:19:36 +00:00
if ( it2 = = visible_gps . end ( ) )
{
2019-02-05 00:31:09 +00:00
std : : cout < < " Using GPS Almanac: Sat " < < it . second . i_satellite_PRN < < " Az: " < < Az < < " El: " < < El < < std : : endl ;
2019-06-29 22:01:54 +00:00
available_satellites . emplace_back ( floor ( El ) ,
( Gnss_Satellite ( std : : string ( " GPS " ) , it . second . i_satellite_PRN ) ) ) ;
2018-11-22 14:19:36 +00:00
}
2018-11-05 16:53:53 +00:00
}
}
std : : map < int , Galileo_Almanac > gal_alm_map = pvt_ptr - > get_galileo_almanac ( ) ;
2019-02-10 13:07:27 +00:00
for ( auto & it : gal_alm_map )
2018-11-05 16:53:53 +00:00
{
2019-02-05 00:31:09 +00:00
alm_t rtklib_alm = alm_to_rtklib ( it . second ) ;
2018-11-05 16:53:53 +00:00
double r_sat [ 3 ] ;
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 ;
2018-11-22 10:59:49 +00:00
alm2pos ( gal_gtime , & rtklib_alm , & r_sat [ 0 ] , & clock_bias_s ) ;
2018-11-05 16:53:53 +00:00
double Az , El , dist_m ;
arma : : vec r_sat_eb_e = arma : : vec { r_sat [ 0 ] , r_sat [ 1 ] , r_sat [ 2 ] } ;
arma : : vec dx = r_sat_eb_e - r_eb_e ;
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 )
{
2019-02-05 00:31:09 +00:00
it2 = std : : find ( visible_gal . begin ( ) , visible_gal . end ( ) , it . second . i_satellite_PRN ) ;
2018-11-22 14:19:36 +00:00
if ( it2 = = visible_gal . end ( ) )
{
2019-02-05 00:31:09 +00:00
std : : cout < < " Using Galileo Almanac: Sat " < < it . second . i_satellite_PRN < < " Az: " < < Az < < " El: " < < El < < std : : endl ;
2019-06-29 22:01:54 +00:00
available_satellites . emplace_back ( floor ( El ) ,
( Gnss_Satellite ( std : : string ( " Galileo " ) , it . second . i_satellite_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
2013-03-20 18:19:26 +00:00
void ControlThread : : gps_acq_assist_data_collector ( )
{
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 ) ;
2019-02-11 20:13:02 +00:00
if ( gps_acq . i_satellite_PRN = = 0 )
{
break ;
}
2013-11-17 10:48:27 +00:00
// DEBUG MESSAGE
std : : cout < < " Acquisition assistance record has arrived from SAT ID "
< < gps_acq . i_satellite_PRN
< < " with Doppler "
< < gps_acq . d_Doppler0
2018-03-03 01:03:39 +00:00
< < " [Hz] " < < std : : endl ;
2013-11-17 10:48:27 +00:00
// insert new acq record to the global ephemeris map
2018-03-03 01:03:39 +00:00
if ( global_gps_acq_assist_map . read ( gps_acq . i_satellite_PRN , gps_acq_old ) )
2013-11-17 10:48:27 +00:00
{
std : : cout < < " Acquisition assistance record updated " < < std : : endl ;
global_gps_acq_assist_map . write ( gps_acq . i_satellite_PRN , gps_acq ) ;
}
else
{
// insert new acq record
2014-03-16 23:25:52 +00:00
LOG ( INFO ) < < " New acq assist record inserted " ;
2013-11-17 10:48:27 +00:00
global_gps_acq_assist_map . write ( gps_acq . i_satellite_PRN , gps_acq ) ;
}
}
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 ;
int msgrcv_size = sizeof ( msg . stop_message ) ;
2016-10-03 15:43:06 +00:00
2016-10-01 15:32:38 +00:00
key_t key = 1102 ;
2016-10-03 11:43:20 +00:00
2018-03-03 01:03:39 +00:00
if ( ( msqid = msgget ( key , 0644 | IPC_CREAT ) ) = = - 1 )
2016-10-03 11:43:20 +00:00
{
2016-10-16 08:00:39 +00:00
perror ( " GNSS-SDR cannot create SysV message queues " ) ;
2016-10-13 10:02:55 +00:00
exit ( 1 ) ;
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
{
if ( msgrcv ( msqid , & msg , msgrcv_size , 1 , 0 ) ! = - 1 )
{
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
{
std : : cout < < " Quit order received, stopping GNSS-SDR !! " < < std : : endl ;
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
{
std : : cout < < " Quit keystroke order received, stopping GNSS-SDR !! " < < std : : endl ;
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 ;
}
2019-02-24 12:22:52 +00:00
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
}