@@ -4,9 +4,7 @@ use log::debug;
4
4
use polyfit_rs:: polyfit_rs:: polyfit;
5
5
use thiserror:: Error ;
6
6
7
- use crate :: prelude:: { Duration , Epoch , FittedData , IonosphericData , TrackData , SV } ;
8
-
9
- use std:: collections:: BTreeMap ;
7
+ use crate :: prelude:: { Duration , Epoch , FittedData , SV } ;
10
8
11
9
/// CGGTTS track formation errors
12
10
#[ derive( Debug , Clone , Error ) ]
@@ -59,22 +57,28 @@ pub struct Observation {
59
57
}
60
58
61
59
impl SVTracker {
62
- /// Creates (allocates) a new [SVTracker] for that particular satellite.
60
+ /// Allocate a new [SVTracker] for that particular satellite.
63
61
///
64
62
/// ## Input
65
- /// - satellite: as [SV]
66
- /// - tolerance: sampling gap tolerance as [Duration]
67
- pub fn new ( sv : SV , gap_tolerance : Option < Duration > ) -> Self {
63
+ /// - satellite: [SV]
64
+ pub fn new ( satellite : SV ) -> Self {
68
65
Self {
69
- sv,
70
66
size : 0 ,
71
67
t0 : None ,
72
68
prev_t : None ,
73
- gap_tolerance,
69
+ sv : satellite,
70
+ gap_tolerance : None ,
74
71
buffer : Vec :: with_capacity ( 16 ) ,
75
72
}
76
73
}
77
74
75
+ /// Define a new [SVTracker] with desired observation gap tolerance.
76
+ pub fn with_gap_tolerance ( & self , tolerance : Duration ) -> Self {
77
+ let mut s = self . clone ( ) ;
78
+ s. gap_tolerance = Some ( tolerance) ;
79
+ s
80
+ }
81
+
78
82
/// Feed new [Observation] at t [Epoch] of observation (sampling).
79
83
/// Although CGGTTS works in UTC internally, we accept any timescale here.
80
84
/// Samples must be provided in chronological order.
@@ -288,14 +292,13 @@ impl SVTracker {
288
292
289
293
#[ cfg( test) ]
290
294
mod test {
291
- use crate :: prelude:: { Duration , Epoch , FittedData , Observation , SVTracker , SV } ;
295
+ use crate :: prelude:: { Duration , Epoch , Observation , SVTracker , SV } ;
292
296
use std:: str:: FromStr ;
293
297
294
298
#[ test]
295
299
fn tracker_no_gap_x3 ( ) {
296
300
let g01 = SV :: from_str ( "G01" ) . unwrap ( ) ;
297
-
298
- let mut tracker = SVTracker :: new ( g01, None ) ;
301
+ let mut tracker = SVTracker :: new ( g01) ;
299
302
300
303
for obs in [
301
304
Observation {
@@ -357,8 +360,7 @@ mod test {
357
360
#[ test]
358
361
fn tracker_no_gap_x4 ( ) {
359
362
let g01 = SV :: from_str ( "G01" ) . unwrap ( ) ;
360
-
361
- let mut tracker = SVTracker :: new ( g01, None ) ;
363
+ let mut tracker = SVTracker :: new ( g01) ;
362
364
363
365
for obs in [
364
366
Observation {
@@ -416,4 +418,216 @@ mod test {
416
418
assert_eq ! ( fitted. elevation_deg, 6.1 ) ;
417
419
assert_eq ! ( fitted. azimuth_deg, 7.1 ) ;
418
420
}
421
+
422
+ #[ test]
423
+ fn tracker_30s_15s_ok ( ) {
424
+ let g01 = SV :: from_str ( "G01" ) . unwrap ( ) ;
425
+ let dt_30s = Duration :: from_str ( "30 s" ) . unwrap ( ) ;
426
+
427
+ let mut tracker = SVTracker :: new ( g01) . with_gap_tolerance ( dt_30s) ;
428
+
429
+ for obs in [
430
+ Observation {
431
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:00 UTC" ) . unwrap ( ) ,
432
+ refsv : 1.0 ,
433
+ refsys : 2.0 ,
434
+ mdtr : 3.0 ,
435
+ mdio : 4.0 ,
436
+ msio : None ,
437
+ elevation : 6.0 ,
438
+ azimuth : 7.0 ,
439
+ } ,
440
+ Observation {
441
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:15 UTC" ) . unwrap ( ) ,
442
+ refsv : 1.1 ,
443
+ refsys : 2.1 ,
444
+ mdtr : 3.1 ,
445
+ mdio : 4.1 ,
446
+ msio : None ,
447
+ elevation : 6.1 ,
448
+ azimuth : 7.1 ,
449
+ } ,
450
+ Observation {
451
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:30 UTC" ) . unwrap ( ) ,
452
+ refsv : 1.1 ,
453
+ refsys : 2.1 ,
454
+ mdtr : 3.1 ,
455
+ mdio : 4.1 ,
456
+ msio : None ,
457
+ elevation : 6.1 ,
458
+ azimuth : 7.1 ,
459
+ } ,
460
+ Observation {
461
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:45 UTC" ) . unwrap ( ) ,
462
+ refsv : 1.1 ,
463
+ refsys : 2.1 ,
464
+ mdtr : 3.1 ,
465
+ mdio : 4.1 ,
466
+ msio : None ,
467
+ elevation : 6.1 ,
468
+ azimuth : 7.1 ,
469
+ } ,
470
+ ] {
471
+ tracker. new_observation ( obs) ;
472
+ }
473
+
474
+ assert ! ( tracker. fit( ) . is_ok( ) ) ;
475
+ }
476
+
477
+ #[ test]
478
+ fn tracker_30s_30s_ok ( ) {
479
+ let g01 = SV :: from_str ( "G01" ) . unwrap ( ) ;
480
+ let dt_30s = Duration :: from_str ( "30 s" ) . unwrap ( ) ;
481
+
482
+ let mut tracker = SVTracker :: new ( g01) . with_gap_tolerance ( dt_30s) ;
483
+
484
+ for obs in [
485
+ Observation {
486
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:00 UTC" ) . unwrap ( ) ,
487
+ refsv : 1.0 ,
488
+ refsys : 2.0 ,
489
+ mdtr : 3.0 ,
490
+ mdio : 4.0 ,
491
+ msio : None ,
492
+ elevation : 6.0 ,
493
+ azimuth : 7.0 ,
494
+ } ,
495
+ Observation {
496
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:30 UTC" ) . unwrap ( ) ,
497
+ refsv : 1.1 ,
498
+ refsys : 2.1 ,
499
+ mdtr : 3.1 ,
500
+ mdio : 4.1 ,
501
+ msio : None ,
502
+ elevation : 6.1 ,
503
+ azimuth : 7.1 ,
504
+ } ,
505
+ Observation {
506
+ epoch : Epoch :: from_str ( "2020-01-01T00:01:00 UTC" ) . unwrap ( ) ,
507
+ refsv : 1.1 ,
508
+ refsys : 2.1 ,
509
+ mdtr : 3.1 ,
510
+ mdio : 4.1 ,
511
+ msio : None ,
512
+ elevation : 6.1 ,
513
+ azimuth : 7.1 ,
514
+ } ,
515
+ Observation {
516
+ epoch : Epoch :: from_str ( "2020-01-01T00:01:30 UTC" ) . unwrap ( ) ,
517
+ refsv : 1.1 ,
518
+ refsys : 2.1 ,
519
+ mdtr : 3.1 ,
520
+ mdio : 4.1 ,
521
+ msio : None ,
522
+ elevation : 6.1 ,
523
+ azimuth : 7.1 ,
524
+ } ,
525
+ ] {
526
+ tracker. new_observation ( obs) ;
527
+ }
528
+
529
+ assert ! ( tracker. fit( ) . is_ok( ) ) ;
530
+
531
+ for obs in [
532
+ Observation {
533
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:00 UTC" ) . unwrap ( ) ,
534
+ refsv : 1.0 ,
535
+ refsys : 2.0 ,
536
+ mdtr : 3.0 ,
537
+ mdio : 4.0 ,
538
+ msio : None ,
539
+ elevation : 6.0 ,
540
+ azimuth : 7.0 ,
541
+ } ,
542
+ Observation {
543
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:30 UTC" ) . unwrap ( ) ,
544
+ refsv : 1.1 ,
545
+ refsys : 2.1 ,
546
+ mdtr : 3.1 ,
547
+ mdio : 4.1 ,
548
+ msio : None ,
549
+ elevation : 6.1 ,
550
+ azimuth : 7.1 ,
551
+ } ,
552
+ Observation {
553
+ epoch : Epoch :: from_str ( "2020-01-01T00:01:00 UTC" ) . unwrap ( ) ,
554
+ refsv : 1.1 ,
555
+ refsys : 2.1 ,
556
+ mdtr : 3.1 ,
557
+ mdio : 4.1 ,
558
+ msio : None ,
559
+ elevation : 6.1 ,
560
+ azimuth : 7.1 ,
561
+ } ,
562
+ Observation {
563
+ epoch : Epoch :: from_str ( "2020-01-01T00:01:15 UTC" ) . unwrap ( ) ,
564
+ refsv : 1.1 ,
565
+ refsys : 2.1 ,
566
+ mdtr : 3.1 ,
567
+ mdio : 4.1 ,
568
+ msio : None ,
569
+ elevation : 6.1 ,
570
+ azimuth : 7.1 ,
571
+ } ,
572
+ ] {
573
+ tracker. new_observation ( obs) ;
574
+ }
575
+
576
+ assert ! ( tracker. fit( ) . is_ok( ) ) ;
577
+ }
578
+
579
+ #[ test]
580
+ fn tracker_30s_nok ( ) {
581
+ let g01 = SV :: from_str ( "G01" ) . unwrap ( ) ;
582
+ let dt_30s = Duration :: from_str ( "30 s" ) . unwrap ( ) ;
583
+
584
+ let mut tracker = SVTracker :: new ( g01) . with_gap_tolerance ( dt_30s) ;
585
+
586
+ for obs in [
587
+ Observation {
588
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:00 UTC" ) . unwrap ( ) ,
589
+ refsv : 1.0 ,
590
+ refsys : 2.0 ,
591
+ mdtr : 3.0 ,
592
+ mdio : 4.0 ,
593
+ msio : None ,
594
+ elevation : 6.0 ,
595
+ azimuth : 7.0 ,
596
+ } ,
597
+ Observation {
598
+ epoch : Epoch :: from_str ( "2020-01-01T00:00:30 UTC" ) . unwrap ( ) ,
599
+ refsv : 1.1 ,
600
+ refsys : 2.1 ,
601
+ mdtr : 3.1 ,
602
+ mdio : 4.1 ,
603
+ msio : None ,
604
+ elevation : 6.1 ,
605
+ azimuth : 7.1 ,
606
+ } ,
607
+ Observation {
608
+ epoch : Epoch :: from_str ( "2020-01-01T00:01:00 UTC" ) . unwrap ( ) ,
609
+ refsv : 1.1 ,
610
+ refsys : 2.1 ,
611
+ mdtr : 3.1 ,
612
+ mdio : 4.1 ,
613
+ msio : None ,
614
+ elevation : 6.1 ,
615
+ azimuth : 7.1 ,
616
+ } ,
617
+ Observation {
618
+ epoch : Epoch :: from_str ( "2020-01-01T00:01:31 UTC" ) . unwrap ( ) ,
619
+ refsv : 1.1 ,
620
+ refsys : 2.1 ,
621
+ mdtr : 3.1 ,
622
+ mdio : 4.1 ,
623
+ msio : None ,
624
+ elevation : 6.1 ,
625
+ azimuth : 7.1 ,
626
+ } ,
627
+ ] {
628
+ tracker. new_observation ( obs) ;
629
+ }
630
+
631
+ assert ! ( tracker. fit( ) . is_err( ) ) ;
632
+ }
419
633
}
0 commit comments