1
- use super :: TimePolynomial ;
1
+ use crate :: {
2
+ merge:: { Error as MergeError , Merge } ,
3
+ processing:: TimePolynomial ,
4
+ } ;
2
5
3
- use hifitime:: { Duration , Epoch , TimeScale } ;
6
+ use hifitime:: { Epoch , TimeScale } ;
4
7
5
8
#[ cfg( doc) ]
6
9
use super :: Timeshift ;
7
10
8
11
/// [GnssAbsoluteTime] is used by applications that need to precisely describe
9
12
/// the actual state of one or several [TimeScale]s. It is used in our [Timeshift] trait
10
13
/// to allow precise [TimeScale] transposition.
11
- #[ derive( Default ) ]
14
+ /// [GnssAbsoluteTime] does not guard about "bad" operations:
15
+ /// - You are responsible for the [TimePolynomial] you store with respect of the
16
+ /// current time.
17
+ /// - We have no means to consider [TimePolynomial]s are now outdated.
18
+ /// You should always maintain [GnssAbsoluteTime] with up to date polynomials.
19
+ /// To avoid memory growth in very long surveying, we propose:
20
+ /// - [GnssAbsoluteTime::outdate_past] to declare past [TimePolynomial]s as outdated
21
+ /// - and [GnssAbsoluteTime::outdate_weekly] to discard [TimePolynomial]s published before that week
22
+ #[ derive( Default , Clone ) ]
12
23
pub struct GnssAbsoluteTime {
13
24
/// Internal [TimePolynomial]s
14
25
polynomials : Vec < TimePolynomial > ,
@@ -22,16 +33,25 @@ impl GnssAbsoluteTime {
22
33
}
23
34
}
24
35
25
- /// Add a new [TimePolynomial] to this management pool .
26
- /// Usually right after its publication .
27
- pub fn add_polynomial ( & mut self , polynomial : TimePolynomial ) {
28
- self . polynomials . retain ( |poly| {
29
- let same_ref = poly . ref_epoch . time_scale == polynomial . ref_epoch . time_scale ;
36
+ /// Discard [TimePolynomial]s that were published prior "now" .
37
+ /// You must have latched newer [TimePolynomial]s with [Self::add_polynomial] for the structure to remain valid .
38
+ pub fn outdate_past ( & mut self , now : Epoch ) {
39
+ self . polynomials . retain ( |poly| poly . ref_epoch > now ) ;
40
+ }
30
41
31
- let same_lhs = poly. ref_epoch . time_scale == polynomial. ref_epoch . time_scale ;
32
- !( same_ref && same_lhs)
42
+ /// Discard [TimePolynomial]s that were published during past week from "now".
43
+ /// You must have latched newer [TimePolynomial]s with [Self::add_polynomial] for the structure to remain valid.
44
+ pub fn outdate_weekly ( & mut self , now : Epoch ) {
45
+ let new_week = now. to_time_of_week ( ) . 0 ;
46
+ self . polynomials . retain ( |poly| {
47
+ let tow = poly. ref_epoch . to_time_of_week ( ) . 0 ;
48
+ tow >= new_week
33
49
} ) ;
50
+ }
34
51
52
+ /// Add a new [TimePolynomial] to this management pool.
53
+ /// Usually right after its publication.
54
+ pub fn add_polynomial ( & mut self , polynomial : TimePolynomial ) {
35
55
self . polynomials . push ( polynomial) ;
36
56
}
37
57
@@ -45,7 +65,17 @@ impl GnssAbsoluteTime {
45
65
if let Some ( poly) = self
46
66
. polynomials
47
67
. iter ( )
48
- . find ( |poly| poly. lhs_timescale == t. time_scale && poly. rhs_timescale == target)
68
+ . filter_map ( |poly| {
69
+ if poly. lhs_timescale == t. time_scale && poly. rhs_timescale == target {
70
+ Some ( poly)
71
+ } else {
72
+ None
73
+ }
74
+ } )
75
+ . min_by_key ( |poly| {
76
+ let transposed = t. to_time_scale ( poly. lhs_timescale ) ;
77
+ transposed - poly. ref_epoch
78
+ } )
49
79
{
50
80
Some (
51
81
t. precise_timescale_conversion ( true , poly. ref_epoch , poly. polynomial , target)
@@ -54,95 +84,171 @@ impl GnssAbsoluteTime {
54
84
} else if let Some ( poly) = self
55
85
. polynomials
56
86
. iter ( )
57
- . find ( |poly| poly. rhs_timescale == t. time_scale && poly. lhs_timescale == target)
87
+ . filter_map ( |poly| {
88
+ if poly. lhs_timescale == target && poly. rhs_timescale == t. time_scale {
89
+ Some ( poly)
90
+ } else {
91
+ None
92
+ }
93
+ } )
94
+ . min_by_key ( |poly| {
95
+ let transposed = t. to_time_scale ( poly. lhs_timescale ) ;
96
+ transposed - poly. ref_epoch
97
+ } )
58
98
{
59
99
Some (
60
100
t. precise_timescale_conversion ( false , poly. ref_epoch , poly. polynomial , target)
61
101
. unwrap ( ) ,
62
102
)
63
103
} else {
64
- for lhs_poly in self . polynomials . iter ( ) {
65
- for rhs_poly in self . polynomials . iter ( ) {
66
- if lhs_poly. lhs_timescale == t. time_scale && rhs_poly. rhs_timescale == target {
67
- // indirect forward transforms
68
-
69
- // |BDT-GST|=a0_bdt & |GST-GPST|=a1 dt_gst
70
- // GST=BDT-a0_bdt
71
- // BDT-a0 dt_bdt - GPST = a1 dt_gpst
72
- // BDT-GPST (foward indirect) = a1 dt_gpst + a0 dt_bdt
73
-
74
- let dt_lhs_s = ( t. to_time_scale ( lhs_poly. lhs_timescale )
75
- - lhs_poly. ref_epoch )
76
- . to_seconds ( ) ;
77
- let dt_rhs_s = ( t. to_time_scale ( rhs_poly. lhs_timescale )
78
- - rhs_poly. ref_epoch )
79
- . to_seconds ( ) ;
80
-
81
- let mut correction = lhs_poly. polynomial . constant . to_seconds ( )
82
- + lhs_poly. polynomial . rate . to_seconds ( ) * dt_lhs_s
83
- + lhs_poly. polynomial . accel . to_seconds ( ) * dt_lhs_s. powi ( 2 ) ;
84
-
85
- // println!("correction = {}", correction);
86
-
87
- correction += rhs_poly. polynomial . constant . to_seconds ( )
88
- + rhs_poly. polynomial . rate . to_seconds ( ) * dt_rhs_s
89
- + rhs_poly. polynomial . accel . to_seconds ( ) * dt_rhs_s. powi ( 2 ) ;
90
-
91
- // println!("total correction = {}", correction);
92
-
93
- return Some (
94
- t. to_time_scale ( rhs_poly. rhs_timescale )
95
- - Duration :: from_seconds ( correction) ,
96
- ) ;
97
- } else if lhs_poly. rhs_timescale == t. time_scale
98
- && rhs_poly. rhs_timescale == target
99
- {
100
- // indirect backward + forward transforms
101
- } else if lhs_poly. lhs_timescale == t. time_scale
102
- && rhs_poly. lhs_timescale == target
103
- {
104
- // indirect forward + backward transforms
105
- } else if lhs_poly. rhs_timescale == t. time_scale
106
- && rhs_poly. lhs_timescale == target
107
- {
108
- // indirect backward transforms
109
-
110
- // |BDT-GST|=a0_bdt & |GST-GPST|=a1 dt_gst
111
- // BDT = a0_bdt + GST
112
- // GPST = GST -a1 dt_gpst
113
- // GPST-BDT (backward indirect) = -a1 -a0
114
-
115
- let dt_lhs_s = ( t. to_time_scale ( lhs_poly. lhs_timescale )
116
- - lhs_poly. ref_epoch )
117
- . to_seconds ( ) ;
118
- let dt_rhs_s = ( t. to_time_scale ( rhs_poly. lhs_timescale )
119
- - rhs_poly. ref_epoch )
120
- . to_seconds ( ) ;
121
-
122
- let correction_a = lhs_poly. polynomial . constant . to_seconds ( )
123
- + lhs_poly. polynomial . rate . to_seconds ( ) * dt_lhs_s
124
- + lhs_poly. polynomial . accel . to_seconds ( ) * dt_lhs_s. powi ( 2 ) ;
125
-
126
- // println!("correction = {}", correction_a);
127
-
128
- let correction_b = rhs_poly. polynomial . constant . to_seconds ( )
129
- + rhs_poly. polynomial . rate . to_seconds ( ) * dt_rhs_s
130
- + rhs_poly. polynomial . accel . to_seconds ( ) * dt_rhs_s. powi ( 2 ) ;
131
-
132
- // println!("correction = {}", correction_b);
133
-
134
- return Some (
135
- t. to_time_scale ( rhs_poly. lhs_timescale )
136
- + Duration :: from_seconds ( correction_a)
137
- + Duration :: from_seconds ( correction_b) ,
138
- ) ;
139
- }
140
- }
141
- }
142
-
104
+ // mixed combinations not supported yet
143
105
None
144
106
}
145
107
}
108
+
109
+ // else if let Some(poly) = self
110
+ // .polynomials
111
+ // .iter()
112
+ // .filter(|poly| {
113
+ // if poly.lhs_timescale == t.time_scale {
114
+ // Some(poly)
115
+ // } else {
116
+ // None
117
+ // }
118
+ // })
119
+ // .min_by_key(|poly| {
120
+ // let transposed = t.to_time_scale(poly.lhs_timescale);
121
+ // transposed - poly.ref_epoch
122
+ // })
123
+ // {
124
+ // // got a forward (1) proposal
125
+ // if let Some(poly) = self
126
+ // .polynomials
127
+ // .iter()
128
+ // .filter(|poly| {
129
+ // if poly.rhs_timescale == target {
130
+ // Some(poly)
131
+ // } else {
132
+ // None
133
+ // }
134
+ // })
135
+ // .min_by_key(|poly| {
136
+ // let transposed = t.to_time_scale(poly.lhs_timescale);
137
+ // transposed - poly.ref_epoch
138
+ // })
139
+ // {
140
+ // // got a forward (2) proposal
141
+ // } else {
142
+ // // got a backward (2) proposal
143
+ // None
144
+ // }
145
+ // } else {
146
+ // None
147
+ // }
148
+ // Some(
149
+ // t.precise_timescale_conversion(true, poly.ref_epoch, poly.polynomial, target)
150
+ // .unwrap(),
151
+ // )
152
+
153
+ // for lhs_poly in self.polynomials.iter() {
154
+ // for rhs_poly in self.polynomials.iter() {
155
+ // if lhs_poly.lhs_timescale == t.time_scale && rhs_poly.rhs_timescale == target {
156
+ // // indirect forward transforms
157
+
158
+ // // |BDT-GST|=a0_bdt & |GST-GPST|=a1 dt_gst
159
+ // // GST=BDT-a0_bdt
160
+ // // BDT-a0 dt_bdt - GPST = a1 dt_gpst
161
+ // // BDT-GPST (foward indirect) = a1 dt_gpst + a0 dt_bdt
162
+
163
+ // let dt_lhs_s = (t.to_time_scale(lhs_poly.lhs_timescale)
164
+ // - lhs_poly.ref_epoch)
165
+ // .to_seconds();
166
+
167
+ // let dt_rhs_s = (t.to_time_scale(rhs_poly.lhs_timescale)
168
+ // - rhs_poly.ref_epoch)
169
+ // .to_seconds();
170
+
171
+ // let mut correction = lhs_poly.polynomial.constant.to_seconds()
172
+ // + lhs_poly.polynomial.rate.to_seconds() * dt_lhs_s
173
+ // + lhs_poly.polynomial.accel.to_seconds() * dt_lhs_s.powi(2);
174
+
175
+ // // println!("correction = {}", correction);
176
+
177
+ // correction += rhs_poly.polynomial.constant.to_seconds()
178
+ // + rhs_poly.polynomial.rate.to_seconds() * dt_rhs_s
179
+ // + rhs_poly.polynomial.accel.to_seconds() * dt_rhs_s.powi(2);
180
+
181
+ // // println!("total correction = {}", correction);
182
+
183
+ // return Some(t.to_time_scale(target) - Duration::from_seconds(correction));
184
+ // } else if lhs_poly.rhs_timescale == t.time_scale
185
+ // && rhs_poly.rhs_timescale == target
186
+ // {
187
+ // // indirect backward + forward transforms
188
+ // } else if lhs_poly.lhs_timescale == t.time_scale
189
+ // && rhs_poly.lhs_timescale == target
190
+ // {
191
+ // // indirect forward + backward transforms
192
+ // } else if lhs_poly.rhs_timescale == t.time_scale
193
+ // && rhs_poly.lhs_timescale == target
194
+ // {
195
+ // // indirect backward transforms
196
+
197
+ // // |BDT-GST|=a0_bdt & |GST-GPST|=a1 dt_gst
198
+ // // BDT = a0_bdt + GST
199
+ // // GPST = GST -a1 dt_gpst
200
+ // // GPST-BDT (backward indirect) = -a1 -a0
201
+
202
+ // let dt_lhs_s = (t.to_time_scale(lhs_poly.lhs_timescale)
203
+ // - lhs_poly.ref_epoch)
204
+ // .to_seconds();
205
+
206
+ // let dt_rhs_s = (t.to_time_scale(rhs_poly.lhs_timescale)
207
+ // - rhs_poly.ref_epoch)
208
+ // .to_seconds();
209
+
210
+ // let correction_a = lhs_poly.polynomial.constant.to_seconds()
211
+ // + lhs_poly.polynomial.rate.to_seconds() * dt_lhs_s
212
+ // + lhs_poly.polynomial.accel.to_seconds() * dt_lhs_s.powi(2);
213
+
214
+ // // println!("correction = {}", correction_a);
215
+
216
+ // let correction_b = rhs_poly.polynomial.constant.to_seconds()
217
+ // + rhs_poly.polynomial.rate.to_seconds() * dt_rhs_s
218
+ // + rhs_poly.polynomial.accel.to_seconds() * dt_rhs_s.powi(2);
219
+
220
+ // // println!("correction = {}", correction_b);
221
+
222
+ // return Some(
223
+ // t.to_time_scale(target)
224
+ // + Duration::from_seconds(correction_a)
225
+ // + Duration::from_seconds(correction_b),
226
+ // );
227
+ // }
228
+ // }
229
+ // }
230
+
231
+ // None
232
+ }
233
+
234
+ impl Merge for GnssAbsoluteTime {
235
+ fn merge ( & self , rhs : & Self ) -> Result < Self , MergeError >
236
+ where
237
+ Self : Sized ,
238
+ {
239
+ let mut s = self . clone ( ) ;
240
+ s. merge_mut ( rhs) ?;
241
+
242
+ Ok ( s)
243
+ }
244
+
245
+ fn merge_mut ( & mut self , rhs : & Self ) -> Result < ( ) , MergeError > {
246
+ // latch new polynomials
247
+ for polynomial in rhs. polynomials . iter ( ) {
248
+ self . add_polynomial ( * polynomial) ;
249
+ }
250
+ Ok ( ( ) )
251
+ }
146
252
}
147
253
148
254
#[ cfg( test) ]
@@ -203,6 +309,7 @@ mod test {
203
309
}
204
310
205
311
#[ test]
312
+ #[ ignore]
206
313
fn test_indirect_forward_transform_not_utc ( ) {
207
314
let t_ref_bdt = Epoch :: from_str ( "2020-01-01T00:00:00 BDT" ) . unwrap ( ) ;
208
315
let t_ref_gst = Epoch :: from_str ( "2020-01-01T00:00:00 GST" ) . unwrap ( ) ;
@@ -313,6 +420,7 @@ mod test {
313
420
}
314
421
315
422
#[ test]
423
+ #[ ignore]
316
424
fn test_indirect_forward_transform_utc ( ) {
317
425
let t_ref_bdt = Epoch :: from_str ( "2020-01-01T00:00:00 BDT" ) . unwrap ( ) ;
318
426
//let t_ref_gst = Epoch::from_str("2020-01-01T00:00:00 GST").unwrap();
0 commit comments