1- use crate :: bias:: RuntimeParam ;
2- use crate :: prelude:: TimeScale ;
3- use map_3d:: deg2rad;
1+ use crate :: { bias:: RuntimeParams , prelude:: TimeScale } ;
42use std:: f64:: consts:: PI ;
53
6- /// Ionospheric Components to attach
7- /// any resolution attempt. Fill as much as you can.
8- /// If this structure is empty, you should then provide observations
9- /// on at least two carrier signals so the solver can estimate this bias.
10- #[ derive( Default ) ]
11- pub struct IonosphereBias {
12- /// Klobuchar Model to apply
13- pub kb_model : Option < KbModel > ,
14- /// Nequick-G model to apply
15- pub ng_model : Option < NgModel > ,
16- /// BDGIM model to apply
17- pub bd_model : Option < BdModel > ,
18- /// Slan Total Electron Density estimate
19- pub stec_meas : Option < f64 > ,
4+ #[ cfg( feature = "serde" ) ]
5+ use serde:: { Deserialize , Serialize } ;
6+
7+ /// Ionopheric delay components to attach to any attempt.
8+ #[ derive( Default , Clone , Copy ) ]
9+ pub enum IonoComponents {
10+ /// Unknown
11+ #[ default]
12+ Unknown ,
13+ /// Provide a [KbModel]
14+ KbModel ( KbModel ) ,
15+ /// Provide a [NgModel]
16+ NgModel ( NgModel ) ,
17+ /// Provide a [BdModel]
18+ BdModel ( BdModel ) ,
19+ /// Provide Slant Total Electron Density [TECu]
20+ Stec ( f64 ) ,
2021}
2122
2223/// Klobuchar Model
@@ -31,30 +32,29 @@ pub struct KbModel {
3132}
3233
3334impl KbModel {
34- pub ( crate ) fn bias ( & self , rtm : & RuntimeParam ) -> Option < f64 > {
35+ pub ( crate ) fn value ( & self , rtm : & RuntimeParams ) -> f64 {
3536 const PHI_P : f64 = 78.3 ;
3637 const R_EARTH : f64 = 6378.0 ;
3738 const LAMBDA_P : f64 = 291.0 ;
3839 const L1_F : f64 = 1575.42E6 ;
3940
40- let ( lat_ddeg, lon_ddeg, _) = rtm. apriori_geo ;
41-
41+ let ( phi_u, lambda_u) = rtm. apriori_rad ;
4242 let fract = R_EARTH / ( R_EARTH + self . h_km ) ;
43- let ( elev, azim) = ( deg2rad ( rtm. elevation ) , deg2rad ( rtm. azimuth ) ) ;
44- let ( phi_u, lambda_u) = ( deg2rad ( lat_ddeg) , deg2rad ( lon_ddeg) ) ;
43+ let ( elev_rad, azim_rad) = ( rtm. elevation_rad , rtm. azimuth_rad ) ;
4544
46- let t_gps = rtm
45+ let t_gpst = rtm
4746 . t
4847 . to_duration_in_time_scale ( TimeScale :: GPST )
4948 . to_seconds ( ) ;
50- let psi = PI / 2.0 - elev - ( fract * elev. cos ( ) ) . asin ( ) ;
51- let phi_i = ( phi_u. sin ( ) * psi. cos ( ) + phi_u. cos ( ) * psi. sin ( ) * azim. cos ( ) ) . asin ( ) ;
52- let lambda_i = lambda_u + azim. sin ( ) * psi / phi_i. cos ( ) ;
49+
50+ let psi = PI / 2.0 - elev_rad - ( fract * elev_rad. cos ( ) ) . asin ( ) ;
51+ let phi_i = ( phi_u. sin ( ) * psi. cos ( ) + phi_u. cos ( ) * psi. sin ( ) * azim_rad. cos ( ) ) . asin ( ) ;
52+ let lambda_i = lambda_u + azim_rad. sin ( ) * psi / phi_i. cos ( ) ;
5353 let phi_m = ( phi_i. sin ( ) * PHI_P . sin ( )
5454 + phi_i. cos ( ) * PHI_P . cos ( ) * ( lambda_i - LAMBDA_P ) . cos ( ) )
5555 . asin ( ) ;
5656
57- let mut t_s = 43.2E3 * lambda_i / PI + t_gps ;
57+ let mut t_s = 43.2E3 * lambda_i / PI + t_gpst ;
5858 if t_s > 86.4E3 {
5959 t_s -= 86.4E3 ;
6060 } else if t_s < 0.0 {
@@ -78,60 +78,89 @@ impl KbModel {
7878 }
7979
8080 let x_i = 2.0 * PI * ( t_s - 50400.0 ) / p_i;
81- let f = 1.0 / ( ( 1.0 - fract * elev . cos ( ) ) . powi ( 2 ) ) . sqrt ( ) ;
81+ let f = 1.0 / ( ( 1.0 - fract * elev_rad . cos ( ) ) . powi ( 2 ) ) . sqrt ( ) ;
8282 let i_1 = match x_i < PI / 2.0 {
8383 true => 5.0 * 10E-9 + a_i * x_i. cos ( ) ,
8484 false => f * 5.0 * 10E-9 ,
8585 } ;
8686
87- Some ( i_1 * ( L1_F / rtm. frequency ) . powi ( 2 ) )
87+ i_1 * ( L1_F / rtm. frequency ) . powi ( 2 )
8888 }
8989}
9090
91- /// Nequick-G Model
91+ /// Nequick-G Model: is not supported yet.
9292#[ derive( Clone , Copy , Default , Debug ) ]
9393pub struct NgModel {
9494 /// alpha coefficients
9595 pub a : ( f64 , f64 , f64 ) ,
9696}
9797
9898impl NgModel {
99- pub ( crate ) fn bias ( & self , _rtm : & RuntimeParam ) -> Option < f64 > {
99+ pub ( crate ) fn value ( & self , _rtm : & RuntimeParams ) -> f64 {
100100 //let phi = deg2rad(rtm.apriori_geo.0);
101101 //let mu = inclination / phi.cos().sqrt();
102- None //TODO
102+ 0.0
103103 }
104104}
105105
106- /// BDGIM Model
106+ /// BDGIM Model: is not supported yet.
107107#[ derive( Clone , Copy , Default , Debug ) ]
108108pub struct BdModel {
109109 /// Alpha coefficients in TECu
110110 pub alpha : ( f64 , f64 , f64 , f64 , f64 , f64 , f64 , f64 , f64 ) ,
111111}
112112
113113impl BdModel {
114- pub ( crate ) fn bias ( & self , _rtm : & RuntimeParam ) -> Option < f64 > {
114+ pub ( crate ) fn value ( & self , _rtm : & RuntimeParams ) -> f64 {
115115 //let phi = deg2rad(rtm.apriori_geo.0);
116116 //let mu = inclination / phi.cos().sqrt();
117- None //TODO
117+ 0.0
118+ }
119+ }
120+
121+ impl IonoComponents {
122+ pub ( crate ) fn value ( & self , rtm : & RuntimeParams ) -> f64 {
123+ match self {
124+ Self :: Unknown => 0.0 ,
125+ Self :: KbModel ( model) => model. value ( rtm) ,
126+ Self :: NgModel ( model) => model. value ( rtm) ,
127+ Self :: BdModel ( model) => model. value ( rtm) ,
128+ Self :: Stec ( stec) => 0.0 , //TODO
129+ }
130+ }
131+ }
132+
133+ /// Modeled (estimated) or measured bias
134+ #[ derive( Debug , Copy , Clone ) ]
135+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
136+ pub enum IonosphereBias {
137+ /// Measured bias in [m]
138+ Measured ( f64 ) ,
139+ /// Modelled bias in [m]
140+ Modeled ( f64 ) ,
141+ }
142+
143+ impl Default for IonosphereBias {
144+ /// Builds a Default "Modeled" Bias with 0 value
145+ fn default ( ) -> Self {
146+ Self :: Modeled ( 0.0 )
118147 }
119148}
120149
121150impl IonosphereBias {
122- pub ( crate ) fn bias ( & self , rtm : & RuntimeParam ) -> Option < f64 > {
123- if let Some ( _stec) = self . stec_meas {
124- // TODO
125- // let alpha = 40.3 * 10E16 / frequency / frequency;
126- None
127- } else if let Some ( kb) = self . kb_model {
128- kb. bias ( rtm)
129- } else if let Some ( ng) = self . ng_model {
130- ng. bias ( rtm)
131- } else if let Some ( bd) = self . bd_model {
132- bd. bias ( rtm)
133- } else {
134- None
151+ /// Returns Bias value in [m]
152+ pub fn value ( & self ) -> f64 {
153+ match self {
154+ Self :: Measured ( bias) => * bias,
155+ Self :: Modeled ( bias) => * bias,
135156 }
136157 }
158+ /// Builds a measured bias in [m]
159+ pub ( crate ) fn measured ( meas_m : f64 ) -> Self {
160+ Self :: Measured ( meas_m)
161+ }
162+ /// Builds a modeled bias in [m]
163+ pub ( crate ) fn modeled ( model_m : f64 ) -> Self {
164+ Self :: Modeled ( model_m)
165+ }
137166}
0 commit comments