2014-06-18 09:04:26 +00:00
/*!
* \ file galileo_e1_ls_pvt . cc
* \ brief Implementation of a Least Squares Position , Velocity , and Time
* ( PVT ) solver , based on K . Borre ' s Matlab receiver .
* \ author Javier Arribas , 2011. jarribas ( at ) cttc . es
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*
2018-05-13 20:49:11 +00:00
* Copyright ( C ) 2010 - 2018 ( see AUTHORS file for a list of contributors )
2014-06-18 09:04:26 +00:00
*
* GNSS - SDR is a software defined Global Navigation
* Satellite Systems receiver
*
* This file is part of GNSS - SDR .
*
* GNSS - SDR is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
2015-01-08 18:49:59 +00:00
* ( at your option ) any later version .
2014-06-18 09:04:26 +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/>.
2014-06-18 09:04:26 +00:00
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
# include "hybrid_ls_pvt.h"
2017-04-12 14:55:34 +00:00
# include "GPS_L1_CA.h"
# include "GPS_L2C.h"
2018-12-09 21:00:09 +00:00
# include "Galileo_E1.h"
2018-06-15 06:24:07 +00:00
# include <boost/date_time/posix_time/posix_time.hpp>
2018-02-26 02:15:53 +00:00
# include <glog/logging.h>
2018-12-09 21:00:09 +00:00
# include <utility>
2014-06-18 09:04:26 +00:00
using google : : LogMessage ;
2015-11-14 13:17:02 +00:00
hybrid_ls_pvt : : hybrid_ls_pvt ( int nchannels , std : : string dump_filename , bool flag_dump_to_file ) : Ls_Pvt ( )
2014-06-18 09:04:26 +00:00
{
// init empty ephemeris for all the available GNSS channels
d_nchannels = nchannels ;
2018-12-03 18:01:47 +00:00
d_dump_filename = std : : move ( dump_filename ) ;
2014-06-18 09:04:26 +00:00
d_flag_dump_enabled = flag_dump_to_file ;
d_galileo_current_time = 0 ;
2015-05-21 18:27:07 +00:00
count_valid_position = 0 ;
2017-08-16 10:45:00 +00:00
this - > set_averaging_flag ( false ) ;
2014-06-18 09:04:26 +00:00
// ############# ENABLE DATA FILE LOG #################
if ( d_flag_dump_enabled = = true )
{
2018-03-03 01:03:39 +00:00
if ( d_dump_file . is_open ( ) = = false )
{
try
{
d_dump_file . exceptions ( std : : ifstream : : failbit | std : : ifstream : : badbit ) ;
d_dump_file . open ( d_dump_filename . c_str ( ) , std : : ios : : out | std : : ios : : binary ) ;
LOG ( INFO ) < < " PVT lib dump enabled Log file: " < < d_dump_filename . c_str ( ) ;
}
catch ( const std : : ifstream : : failure & e )
{
LOG ( WARNING ) < < " Exception opening PVT lib dump file " < < e . what ( ) ;
}
}
2014-06-18 09:04:26 +00:00
}
}
hybrid_ls_pvt : : ~ hybrid_ls_pvt ( )
{
2017-08-14 11:59:00 +00:00
if ( d_dump_file . is_open ( ) = = true )
{
try
2018-03-03 01:03:39 +00:00
{
2017-08-14 11:59:00 +00:00
d_dump_file . close ( ) ;
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & ex )
{
2017-08-14 11:59:00 +00:00
LOG ( WARNING ) < < " Exception in destructor closing the dump file " < < ex . what ( ) ;
2018-03-03 01:03:39 +00:00
}
2017-08-14 11:59:00 +00:00
}
2014-06-18 09:04:26 +00:00
}
2018-03-03 01:03:39 +00:00
bool hybrid_ls_pvt : : get_PVT ( std : : map < int , Gnss_Synchro > gnss_observables_map , double hybrid_current_time , bool flag_averaging )
2014-06-18 09:04:26 +00:00
{
2018-03-03 01:03:39 +00:00
std : : map < int , Gnss_Synchro > : : iterator gnss_observables_iter ;
std : : map < int , Galileo_Ephemeris > : : iterator galileo_ephemeris_iter ;
std : : map < int , Gps_Ephemeris > : : iterator gps_ephemeris_iter ;
std : : map < int , Gps_CNAV_Ephemeris > : : iterator gps_cnav_ephemeris_iter ;
2016-11-02 16:35:40 +00:00
2018-03-03 01:03:39 +00:00
arma : : vec W ; // channels weight vector
arma : : vec obs ; // pseudoranges observation vector
arma : : mat satpos ; // satellite positions matrix
2014-06-18 09:04:26 +00:00
int Galileo_week_number = 0 ;
2015-12-08 19:24:36 +00:00
int GPS_week = 0 ;
double utc = 0.0 ;
double GST = 0.0 ;
2017-03-23 14:45:41 +00:00
double secondsperweek = 604800.0 ;
2016-03-29 16:40:00 +00:00
//double utc_tx_corrected = 0.0; //utc computed at tx_time_corrected, added for Galileo constellation (in GPS utc is directly computed at TX_time_corrected_s)
double TX_time_corrected_s = 0.0 ;
2015-12-08 19:24:36 +00:00
double SV_clock_bias_s = 0.0 ;
2014-06-18 09:04:26 +00:00
2017-08-16 10:45:00 +00:00
this - > set_averaging_flag ( flag_averaging ) ;
2014-06-18 09:04:26 +00:00
// ********************************************************************************
// ****** PREPARE THE LEAST SQUARES DATA (SV POSITIONS MATRIX AND OBS VECTORS) ****
// ********************************************************************************
2018-03-03 01:03:39 +00:00
int valid_obs = 0 ; //valid observations counter
2016-11-03 13:33:20 +00:00
2018-03-03 01:03:39 +00:00
for ( gnss_observables_iter = gnss_observables_map . begin ( ) ;
gnss_observables_iter ! = gnss_observables_map . end ( ) ;
gnss_observables_iter + + )
2017-02-03 12:00:50 +00:00
{
2018-03-03 01:03:39 +00:00
switch ( gnss_observables_iter - > second . System )
2017-02-03 12:00:50 +00:00
{
2018-03-03 01:03:39 +00:00
case ' E ' :
{
// 1 Gal - find the ephemeris for the current GALILEO SV observation. The SV PRN ID is the map key
galileo_ephemeris_iter = galileo_ephemeris_map . find ( gnss_observables_iter - > second . PRN ) ;
if ( galileo_ephemeris_iter ! = galileo_ephemeris_map . end ( ) )
{
/*!
2017-02-06 18:24:17 +00:00
* \ todo Place here the satellite CN0 ( power level , or weight factor )
*/
2018-03-03 01:03:39 +00:00
W . resize ( valid_obs + 1 , 1 ) ;
W ( valid_obs ) = 1 ;
// COMMON RX TIME PVT ALGORITHM
double Rx_time = hybrid_current_time ;
double Tx_time = Rx_time - gnss_observables_iter - > second . Pseudorange_m / GALILEO_C_m_s ;
// 2- compute the clock drift using the clock model (broadcast) for this SV
SV_clock_bias_s = galileo_ephemeris_iter - > second . sv_clock_drift ( Tx_time ) ;
// 3- compute the current ECEF position for this SV using corrected TX time
TX_time_corrected_s = Tx_time - SV_clock_bias_s ;
galileo_ephemeris_iter - > second . satellitePosition ( TX_time_corrected_s ) ;
//store satellite positions in a matrix
satpos . resize ( 3 , valid_obs + 1 ) ;
satpos ( 0 , valid_obs ) = galileo_ephemeris_iter - > second . d_satpos_X ;
satpos ( 1 , valid_obs ) = galileo_ephemeris_iter - > second . d_satpos_Y ;
satpos ( 2 , valid_obs ) = galileo_ephemeris_iter - > second . d_satpos_Z ;
// 4- fill the observations vector with the corrected observables
obs . resize ( valid_obs + 1 , 1 ) ;
obs ( valid_obs ) = gnss_observables_iter - > second . Pseudorange_m + SV_clock_bias_s * GALILEO_C_m_s - this - > get_time_offset_s ( ) * GALILEO_C_m_s ;
Galileo_week_number = galileo_ephemeris_iter - > second . WN_5 ; //for GST
GST = galileo_ephemeris_iter - > second . Galileo_System_Time ( Galileo_week_number , hybrid_current_time ) ;
// SV ECEF DEBUG OUTPUT
DLOG ( INFO ) < < " ECEF satellite SV ID= " < < galileo_ephemeris_iter - > second . i_satellite_PRN
< < " X= " < < galileo_ephemeris_iter - > second . d_satpos_X
< < " [m] Y= " < < galileo_ephemeris_iter - > second . d_satpos_Y
< < " [m] Z= " < < galileo_ephemeris_iter - > second . d_satpos_Z
< < " [m] PR_obs= " < < obs ( valid_obs ) < < " [m] " ;
valid_obs + + ;
}
else // the ephemeris are not available for this SV
{
DLOG ( INFO ) < < " No ephemeris data for SV " < < gnss_observables_iter - > second . PRN ;
}
break ;
}
case ' G ' :
{
// 1 GPS - find the ephemeris for the current GPS SV observation. The SV PRN ID is the map key
std : : string sig_ ( gnss_observables_iter - > second . Signal ) ;
2018-12-02 14:42:38 +00:00
if ( sig_ = = " 1C " )
2018-03-03 01:03:39 +00:00
{
gps_ephemeris_iter = gps_ephemeris_map . find ( gnss_observables_iter - > second . PRN ) ;
if ( gps_ephemeris_iter ! = gps_ephemeris_map . end ( ) )
{
/*!
2017-02-06 18:24:17 +00:00
* \ todo Place here the satellite CN0 ( power level , or weight factor )
*/
2018-03-03 01:03:39 +00:00
W . resize ( valid_obs + 1 , 1 ) ;
W ( valid_obs ) = 1 ;
// COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files)
// first estimate of transmit time
double Rx_time = hybrid_current_time ;
double Tx_time = Rx_time - gnss_observables_iter - > second . Pseudorange_m / GPS_C_m_s ;
// 2- compute the clock drift using the clock model (broadcast) for this SV, not including relativistic effect
SV_clock_bias_s = gps_ephemeris_iter - > second . sv_clock_drift ( Tx_time ) ; //- gps_ephemeris_iter->second.d_TGD;
// 3- compute the current ECEF position for this SV using corrected TX time and obtain clock bias including relativistic effect
TX_time_corrected_s = Tx_time - SV_clock_bias_s ;
double dtr = gps_ephemeris_iter - > second . satellitePosition ( TX_time_corrected_s ) ;
//store satellite positions in a matrix
satpos . resize ( 3 , valid_obs + 1 ) ;
satpos ( 0 , valid_obs ) = gps_ephemeris_iter - > second . d_satpos_X ;
satpos ( 1 , valid_obs ) = gps_ephemeris_iter - > second . d_satpos_Y ;
satpos ( 2 , valid_obs ) = gps_ephemeris_iter - > second . d_satpos_Z ;
// 4- fill the observations vector with the corrected pseudoranges
// compute code bias: TGD for single frequency
// See IS-GPS-200E section 20.3.3.3.3.2
double sqrt_Gamma = GPS_L1_FREQ_HZ / GPS_L2_FREQ_HZ ;
double Gamma = sqrt_Gamma * sqrt_Gamma ;
double P1_P2 = ( 1.0 - Gamma ) * ( gps_ephemeris_iter - > second . d_TGD * GPS_C_m_s ) ;
double Code_bias_m = P1_P2 / ( 1.0 - Gamma ) ;
obs . resize ( valid_obs + 1 , 1 ) ;
obs ( valid_obs ) = gnss_observables_iter - > second . Pseudorange_m + dtr * GPS_C_m_s - Code_bias_m - this - > get_time_offset_s ( ) * GPS_C_m_s ;
// SV ECEF DEBUG OUTPUT
LOG ( INFO ) < < " (new)ECEF GPS L1 CA satellite SV ID= " < < gps_ephemeris_iter - > second . i_satellite_PRN
< < " TX Time corrected= " < < TX_time_corrected_s < < " X= " < < gps_ephemeris_iter - > second . d_satpos_X
< < " [m] Y= " < < gps_ephemeris_iter - > second . d_satpos_Y
< < " [m] Z= " < < gps_ephemeris_iter - > second . d_satpos_Z
< < " [m] PR_obs= " < < obs ( valid_obs ) < < " [m] " ;
valid_obs + + ;
// compute the UTC time for this SV (just to print the associated UTC timestamp)
GPS_week = gps_ephemeris_iter - > second . i_GPS_week ;
}
else // the ephemeris are not available for this SV
{
DLOG ( INFO ) < < " No ephemeris data for SV " < < gnss_observables_iter - > first ;
}
}
2018-12-02 14:42:38 +00:00
if ( sig_ = = " 2S " )
2018-03-03 01:03:39 +00:00
{
gps_cnav_ephemeris_iter = gps_cnav_ephemeris_map . find ( gnss_observables_iter - > second . PRN ) ;
if ( gps_cnav_ephemeris_iter ! = gps_cnav_ephemeris_map . end ( ) )
{
/*!
2017-02-06 18:24:17 +00:00
* \ todo Place here the satellite CN0 ( power level , or weight factor )
*/
2018-03-03 01:03:39 +00:00
W . resize ( valid_obs + 1 , 1 ) ;
W ( valid_obs ) = 1 ;
// COMMON RX TIME PVT ALGORITHM MODIFICATION (Like RINEX files)
// first estimate of transmit time
double Rx_time = hybrid_current_time ;
double Tx_time = Rx_time - gnss_observables_iter - > second . Pseudorange_m / GPS_C_m_s ;
// 2- compute the clock drift using the clock model (broadcast) for this SV
SV_clock_bias_s = gps_cnav_ephemeris_iter - > second . sv_clock_drift ( Tx_time ) ;
// 3- compute the current ECEF position for this SV using corrected TX time
TX_time_corrected_s = Tx_time - SV_clock_bias_s ;
//std::cout<<"TX time["<<gps_cnav_ephemeris_iter->second.i_satellite_PRN<<"]="<<TX_time_corrected_s<<std::endl;
double dtr = gps_cnav_ephemeris_iter - > second . satellitePosition ( TX_time_corrected_s ) ;
//store satellite positions in a matrix
satpos . resize ( 3 , valid_obs + 1 ) ;
satpos ( 0 , valid_obs ) = gps_cnav_ephemeris_iter - > second . d_satpos_X ;
satpos ( 1 , valid_obs ) = gps_cnav_ephemeris_iter - > second . d_satpos_Y ;
satpos ( 2 , valid_obs ) = gps_cnav_ephemeris_iter - > second . d_satpos_Z ;
// 4- fill the observations vector with the corrected observables
obs . resize ( valid_obs + 1 , 1 ) ;
obs ( valid_obs ) = gnss_observables_iter - > second . Pseudorange_m + dtr * GPS_C_m_s + SV_clock_bias_s * GPS_C_m_s ;
GPS_week = gps_cnav_ephemeris_iter - > second . i_GPS_week ;
GPS_week = GPS_week % 1024 ; //Necessary due to the increase of WN bits in CNAV message (10 in GPS NAV and 13 in CNAV)
// SV ECEF DEBUG OUTPUT
LOG ( INFO ) < < " (new)ECEF GPS L2M satellite SV ID= " < < gps_cnav_ephemeris_iter - > second . i_satellite_PRN
< < " TX Time corrected= " < < TX_time_corrected_s
< < " X= " < < gps_cnav_ephemeris_iter - > second . d_satpos_X
< < " [m] Y= " < < gps_cnav_ephemeris_iter - > second . d_satpos_Y
< < " [m] Z= " < < gps_cnav_ephemeris_iter - > second . d_satpos_Z
< < " [m] PR_obs= " < < obs ( valid_obs ) < < " [m] " ;
valid_obs + + ;
}
else // the ephemeris are not available for this SV
{
DLOG ( INFO ) < < " No ephemeris data for SV " < < gnss_observables_iter - > second . PRN ;
}
}
break ;
}
default :
DLOG ( INFO ) < < " Hybrid observables: Unknown GNSS " ;
2017-02-06 18:24:17 +00:00
break ;
2017-02-03 12:00:50 +00:00
}
}
2014-09-05 10:44:51 +00:00
2014-06-18 09:04:26 +00:00
// ********************************************************************************
// ****** SOLVE LEAST SQUARES******************************************************
// ********************************************************************************
2017-08-16 10:45:00 +00:00
this - > set_num_valid_observations ( valid_obs ) ;
2016-11-03 13:33:20 +00:00
2014-06-30 15:48:01 +00:00
LOG ( INFO ) < < " HYBRID PVT: valid observations= " < < valid_obs ;
2014-06-18 09:04:26 +00:00
2018-03-03 01:03:39 +00:00
if ( valid_obs > = 4 )
2017-02-06 18:24:17 +00:00
{
arma : : vec rx_position_and_time ;
DLOG ( INFO ) < < " satpos= " < < satpos ;
DLOG ( INFO ) < < " obs= " < < obs ;
DLOG ( INFO ) < < " W= " < < W ;
try
2018-03-03 01:03:39 +00:00
{
2017-02-06 18:24:17 +00:00
// check if this is the initial position computation
2017-08-16 10:45:00 +00:00
if ( this - > get_time_offset_s ( ) = = 0 )
2017-02-06 18:24:17 +00:00
{
// execute Bancroft's algorithm to estimate initial receiver position and time
DLOG ( INFO ) < < " Executing Bancroft algorithm... " ;
rx_position_and_time = bancroftPos ( satpos . t ( ) , obs ) ;
2018-03-03 01:03:39 +00:00
this - > set_rx_pos ( rx_position_and_time . rows ( 0 , 2 ) ) ; // save ECEF position for the next iteration
this - > set_time_offset_s ( rx_position_and_time ( 3 ) / GPS_C_m_s ) ; // save time for the next iteration [meters]->[seconds]
2017-02-06 18:24:17 +00:00
}
// Execute WLS using previous position as the initialization point
rx_position_and_time = leastSquarePos ( satpos , obs , W ) ;
2018-03-03 01:03:39 +00:00
this - > set_rx_pos ( rx_position_and_time . rows ( 0 , 2 ) ) ; // save ECEF position for the next iteration
this - > set_time_offset_s ( this - > get_time_offset_s ( ) + rx_position_and_time ( 3 ) / GPS_C_m_s ) ; // accumulate the rx time error for the next iteration [meters]->[seconds]
2017-02-06 18:24:17 +00:00
DLOG ( INFO ) < < " Hybrid Position at TOW= " < < hybrid_current_time < < " in ECEF (X,Y,Z,t[meters]) = " < < rx_position_and_time ;
2017-08-16 10:45:00 +00:00
DLOG ( INFO ) < < " Accumulated rx clock error= " < < this - > get_time_offset_s ( ) < < " clock error for this iteration= " < < rx_position_and_time ( 3 ) / GPS_C_m_s < < " [s] " ;
2017-02-06 18:24:17 +00:00
// Compute GST and Gregorian time
2018-03-03 01:03:39 +00:00
if ( GST ! = 0.0 )
2017-02-06 18:24:17 +00:00
{
utc = galileo_utc_model . GST_to_UTC_time ( GST , Galileo_week_number ) ;
}
else
{
utc = gps_utc_model . utc_time ( TX_time_corrected_s , GPS_week ) + secondsperweek * static_cast < double > ( GPS_week ) ;
}
// get time string Gregorian calendar
2018-06-15 15:21:31 +00:00
boost : : posix_time : : time_duration t = boost : : posix_time : : milliseconds ( static_cast < long > ( utc * 1000.0 ) ) ;
2017-02-06 18:24:17 +00:00
// 22 August 1999 00:00 last Galileo start GST epoch (ICD sec 5.1.2)
boost : : posix_time : : ptime p_time ( boost : : gregorian : : date ( 1999 , 8 , 22 ) , t ) ;
2017-08-16 10:45:00 +00:00
this - > set_position_UTC_time ( p_time ) ;
2017-02-06 18:24:17 +00:00
2018-11-08 16:13:11 +00:00
cart2geo ( static_cast < double > ( rx_position_and_time ( 0 ) ) , static_cast < double > ( rx_position_and_time ( 1 ) ) , static_cast < double > ( rx_position_and_time ( 2 ) ) , 4 ) ;
2017-02-06 18:24:17 +00:00
DLOG ( INFO ) < < " Hybrid Position at " < < boost : : posix_time : : to_simple_string ( p_time )
2017-08-16 10:45:00 +00:00
< < " is Lat = " < < this - > get_latitude ( ) < < " [deg], Long = " < < this - > get_longitude ( )
2018-03-03 01:03:39 +00:00
< < " [deg], Height= " < < this - > get_height ( ) < < " [m] "
< < " RX time offset= " < < this - > get_time_offset_s ( ) < < " [s] " ;
2017-02-06 18:24:17 +00:00
// ######## LOG FILE #########
2018-03-03 01:03:39 +00:00
if ( d_flag_dump_enabled = = true )
2017-02-06 18:24:17 +00:00
{
// MULTIPLEXED FILE RECORDING - Record results to file
try
2018-03-03 01:03:39 +00:00
{
2017-02-06 18:24:17 +00:00
double tmp_double ;
// PVT GPS time
tmp_double = hybrid_current_time ;
2017-08-19 07:16:10 +00:00
d_dump_file . write ( reinterpret_cast < char * > ( & tmp_double ) , sizeof ( double ) ) ;
2017-02-06 18:24:17 +00:00
// ECEF User Position East [m]
tmp_double = rx_position_and_time ( 0 ) ;
2017-08-19 07:16:10 +00:00
d_dump_file . write ( reinterpret_cast < char * > ( & tmp_double ) , sizeof ( double ) ) ;
2017-02-06 18:24:17 +00:00
// ECEF User Position North [m]
tmp_double = rx_position_and_time ( 1 ) ;
2017-08-19 07:16:10 +00:00
d_dump_file . write ( reinterpret_cast < char * > ( & tmp_double ) , sizeof ( double ) ) ;
2017-02-06 18:24:17 +00:00
// ECEF User Position Up [m]
tmp_double = rx_position_and_time ( 2 ) ;
2017-08-19 07:16:10 +00:00
d_dump_file . write ( reinterpret_cast < char * > ( & tmp_double ) , sizeof ( double ) ) ;
2017-02-06 18:24:17 +00:00
// User clock offset [s]
tmp_double = rx_position_and_time ( 3 ) ;
2017-08-19 07:16:10 +00:00
d_dump_file . write ( reinterpret_cast < char * > ( & tmp_double ) , sizeof ( double ) ) ;
2017-02-06 18:24:17 +00:00
// GEO user position Latitude [deg]
2017-08-16 10:45:00 +00:00
tmp_double = this - > get_latitude ( ) ;
2017-08-19 07:16:10 +00:00
d_dump_file . write ( reinterpret_cast < char * > ( & tmp_double ) , sizeof ( double ) ) ;
2017-02-06 18:24:17 +00:00
// GEO user position Longitude [deg]
2017-08-16 10:45:00 +00:00
tmp_double = this - > get_longitude ( ) ;
2017-08-19 07:16:10 +00:00
d_dump_file . write ( reinterpret_cast < char * > ( & tmp_double ) , sizeof ( double ) ) ;
2017-02-06 18:24:17 +00:00
// GEO user position Height [m]
2017-08-16 10:45:00 +00:00
tmp_double = this - > get_height ( ) ;
2017-08-19 07:16:10 +00:00
d_dump_file . write ( reinterpret_cast < char * > ( & tmp_double ) , sizeof ( double ) ) ;
2018-03-03 01:03:39 +00:00
}
2017-02-06 18:24:17 +00:00
catch ( const std : : ifstream : : failure & e )
2018-03-03 01:03:39 +00:00
{
2017-02-06 18:24:17 +00:00
LOG ( WARNING ) < < " Exception writing PVT LS dump file " < < e . what ( ) ;
2018-03-03 01:03:39 +00:00
}
2017-02-06 18:24:17 +00:00
}
// MOVING AVERAGE PVT
2017-08-16 10:45:00 +00:00
this - > perform_pos_averaging ( ) ;
2018-03-03 01:03:39 +00:00
}
catch ( const std : : exception & e )
{
this - > set_time_offset_s ( 0.0 ) ; //reset rx time estimation
2017-02-06 18:24:17 +00:00
LOG ( WARNING ) < < " Problem with the solver, invalid solution! " < < e . what ( ) ;
2017-08-16 10:45:00 +00:00
this - > set_valid_position ( false ) ;
2018-03-03 01:03:39 +00:00
}
2017-02-06 18:24:17 +00:00
}
else
2017-02-06 16:51:11 +00:00
{
2017-08-16 10:45:00 +00:00
this - > set_valid_position ( false ) ;
2017-02-06 16:51:11 +00:00
}
2017-08-16 10:45:00 +00:00
return this - > is_valid_position ( ) ;
2014-06-18 09:04:26 +00:00
}