Skip to content

Commit a1798d6

Browse files
authored
NAV V2, V3 header formatting (#338)
Signed-off-by: Guillaume W. Bres <[email protected]>
1 parent 5efb878 commit a1798d6

File tree

6 files changed

+126
-57
lines changed

6 files changed

+126
-57
lines changed

src/header/parsing.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,13 @@ impl Header {
6565
let mut current_constell: Option<Constellation> = None;
6666

6767
let mut observation = ObservationHeader::default();
68+
let mut nav = NavigationHeader::default();
6869
let mut meteo = MeteoHeader::default();
6970
let mut clock = ClockHeader::default();
7071
let mut antex = AntexHeader::default();
7172
let mut ionex = IonexHeaderFields::default();
7273
let mut doris = DorisHeader::default();
7374

74-
let mut nav = NavigationHeader::default();
75-
let mut nav_ts = TimeScale::GPST;
76-
77-
let mut time_offsets = Vec::<TimeOffset>::new();
78-
7975
for l in reader.lines() {
8076
let line = l.unwrap();
8177
if line.len() < 60 {
@@ -805,15 +801,15 @@ impl Header {
805801
}
806802
} else if marker.contains("DELTA-UTC") {
807803
if let Ok(time_offset) = TimeOffset::parse_v2_delta_utc(content) {
808-
time_offsets.push(time_offset);
804+
nav = nav.with_time_offset(time_offset);
809805
}
810806
} else if marker.contains("CORR TO SYSTEM TIME") {
811807
if let Ok(time_offset) = TimeOffset::parse_v2_corr_to_system_time(content) {
812-
time_offsets.push(time_offset);
808+
nav = nav.with_time_offset(time_offset);
813809
}
814810
} else if marker.contains("TIME SYSTEM CORR") {
815811
if let Ok(time_offset) = TimeOffset::parse_v3(content) {
816-
time_offsets.push(time_offset);
812+
nav = nav.with_time_offset(time_offset);
817813
}
818814
} else if marker.contains("TIME SYSTEM ID") {
819815
let timescale = content.trim();

src/navigation/formatting.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,30 @@ impl NavFormatter {
3131
precision: 4,
3232
}
3333
}
34+
35+
pub fn new_time_system_correction_v2(value: f64) -> Self {
36+
Self {
37+
value,
38+
width: 17,
39+
precision: 12,
40+
}
41+
}
42+
43+
pub fn new_time_system_correction_v3_offset(value: f64) -> Self {
44+
Self {
45+
value,
46+
width: 14,
47+
precision: 10,
48+
}
49+
}
50+
51+
pub fn new_time_system_correction_v3_drift(value: f64) -> Self {
52+
Self {
53+
value,
54+
width: 13,
55+
precision: 9,
56+
}
57+
}
3458
}
3559

3660
impl std::fmt::Display for NavFormatter {
@@ -235,6 +259,33 @@ mod test {
235259
}
236260
}
237261

262+
#[test]
263+
fn system_time_corr_v2_formatter() {
264+
for (value, expected) in [(-1.862645149231E-09, "-1.862645149231E-09")] {
265+
let formatted = NavFormatter::new_time_system_correction_v2(value);
266+
assert_eq!(formatted.to_string(), expected);
267+
}
268+
}
269+
270+
#[test]
271+
fn system_time_corr_v3_formatter() {
272+
for (value, expected) in [
273+
(0.0000000000E+00, " 0.0000000000E+00"),
274+
(2.1536834538E-09, " 2.1536834538E-09"),
275+
] {
276+
let formatted = NavFormatter::new_time_system_correction_v3_offset(value);
277+
assert_eq!(formatted.to_string(), expected);
278+
}
279+
280+
for (value, expected) in [
281+
(-3.019806627E-14, "-3.019806627E-14"),
282+
(-9.769962617E-15, "-9.769962617E-15"),
283+
] {
284+
let formatted = NavFormatter::new_time_system_correction_v3_drift(value);
285+
assert_eq!(formatted.to_string(), expected);
286+
}
287+
}
288+
238289
#[test]
239290
fn nav_fmt_v2v3() {
240291
let gal = Constellation::Galileo;

src/navigation/time/formatting.rs

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::{
22
epoch::epoch_decompose,
33
error::FormattingError,
4+
fmt_rinex,
45
navigation::{formatting::NavFormatter, time::TimeOffset},
56
prelude::{Epoch, TimeScale},
67
};
@@ -32,13 +33,19 @@ impl TimeOffset {
3233
&self,
3334
w: &mut BufWriter<W>,
3435
) -> Result<(), FormattingError> {
35-
write!(
36+
writeln!(
3637
w,
37-
" {}{} {:8} {:8} DELTA-UTC: A0,A1,T,W",
38-
NavFormatter::new(self.polynomials.0),
39-
NavFormatter::new(self.polynomials.1),
40-
self.t_ref.1 / 1_000_000_000,
41-
self.t_ref.0,
38+
"{}",
39+
fmt_rinex(
40+
&format!(
41+
" {}{} {:8} {:8}",
42+
NavFormatter::new_time_system_correction_v2(self.polynomials.0),
43+
NavFormatter::new_time_system_correction_v2(self.polynomials.1),
44+
self.t_ref.1 / 1_000_000_000,
45+
self.t_ref.0,
46+
),
47+
"DELTA-UTC: A0,A1,T,W",
48+
),
4249
)?;
4350

4451
Ok(())
@@ -53,40 +60,41 @@ impl TimeOffset {
5360

5461
let (y, m, d, _, _, _, _) = epoch_decompose(t);
5562

56-
write!(
63+
writeln!(
5764
w,
58-
"{:6}{:6}{:6} {}",
59-
y,
60-
m,
61-
d,
62-
NavFormatter::new(self.polynomials.0)
65+
"{}",
66+
fmt_rinex(
67+
&format!(
68+
"{:6}{:6}{:6} {}",
69+
y,
70+
m,
71+
d,
72+
NavFormatter::new_time_system_correction_v2(self.polynomials.0)
73+
),
74+
"CORR TO SYSTEM TIME",
75+
),
6376
)?;
6477

6578
Ok(())
6679
}
6780

6881
/// Format [TimeOffset] according to RINEXv3 standard
6982
pub(crate) fn format_v3<W: Write>(&self, w: &mut BufWriter<W>) -> Result<(), FormattingError> {
70-
write!(w, "{} ", self.to_lhs_rhs_timescales())?;
71-
72-
// TODO: convert to NavFormatter with programmable precision
73-
if self.polynomials.0 == 0.0 {
74-
write!(w, " 0.0000000000e+00",)?;
75-
} else if self.polynomials.0.is_sign_negative() {
76-
write!(w, "{:14.10E} ", self.polynomials.0,)?;
77-
} else {
78-
write!(w, " {:14.10E} ", self.polynomials.0,)?;
79-
}
80-
81-
if self.polynomials.1 == 0.0 {
82-
write!(w, " 0.000000000e+00 ",)?;
83-
} else if self.polynomials.1.is_sign_negative() {
84-
write!(w, "{:14.9E} ", self.polynomials.1,)?;
85-
} else {
86-
write!(w, " {:14.9E} ", self.polynomials.1,)?;
87-
}
88-
89-
write!(w, "{:6}{:5}", self.t_ref.1 / 1_000_000_000, self.t_ref.0)?;
83+
writeln!(
84+
w,
85+
"{}",
86+
fmt_rinex(
87+
&format!(
88+
"{} {}{} {:6}{:5}",
89+
self.to_lhs_rhs_timescales(),
90+
NavFormatter::new_time_system_correction_v3_offset(self.polynomials.0),
91+
NavFormatter::new_time_system_correction_v3_drift(self.polynomials.1),
92+
self.t_ref.1 / 1_000_000_000,
93+
self.t_ref.0
94+
),
95+
"TIME SYSTEM CORR"
96+
),
97+
)?;
9098

9199
Ok(())
92100
}
@@ -95,9 +103,9 @@ impl TimeOffset {
95103
let t = Epoch::from_time_of_week(self.t_ref.0, self.t_ref.1, self.lhs);
96104
let (y, m, d, hh, mm, ss, _) = epoch_decompose(t);
97105

98-
write!(
106+
writeln!(
99107
w,
100-
" {:04} {:02} {:02} {:02} {:02} {:02} {}\n",
108+
" {:04} {:02} {:02} {:02} {:02} {:02} {}",
101109
y,
102110
m,
103111
d,
@@ -107,7 +115,7 @@ impl TimeOffset {
107115
self.to_lhs_rhs_timescales(),
108116
)?;
109117

110-
write!(
118+
writeln!(
111119
w,
112120
" {}{}{}{}",
113121
NavFormatter::new((self.t_ref.1 / 1_000_000_000) as f64),

src/navigation/time/parsing.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,11 @@ mod test {
268268
// IRGP -4.9476511776e-10-2.664535259e-15 432288 2138 TIME SYSTEM CORR
269269

270270
let content = "XXXX 1.7840648070e-08 5.773159728e-14 432288 2138 ";
271-
272271
assert!(TimeOffset::parse_v3(content).is_err());
273272

274273
for (content, a0, a1, week, sec, lhs, rhs) in [
275274
(
276-
"GAUT 1.8626451492e-09-8.881784197e-16 432000 2138 ",
275+
"GAUT 1.8626451492E-09-8.881784197E-16 432000 2138 TIME SYSTEM CORR\n",
277276
1.8626451492e-09,
278277
-8.881784197e-16,
279278
2138,
@@ -282,7 +281,7 @@ mod test {
282281
TimeScale::UTC,
283282
),
284283
(
285-
"GPUT -3.7252902985e-09-1.065814104e-14 61440 2139 ",
284+
"GPUT -3.7252902985E-09-1.065814104E-14 61440 2139 TIME SYSTEM CORR\n",
286285
-3.7252902985e-09,
287286
-1.065814104e-14,
288287
2139,
@@ -291,7 +290,7 @@ mod test {
291290
TimeScale::UTC,
292291
),
293292
(
294-
"GAGP 2.1536834538e-09-9.769962617e-15 432000 2138 ",
293+
"GAGP 2.1536834538E-09-9.769962617E-15 432000 2138 TIME SYSTEM CORR\n",
295294
2.1536834538e-09,
296295
-9.769962617e-15,
297296
2138,
@@ -300,7 +299,7 @@ mod test {
300299
TimeScale::GPST,
301300
),
302301
(
303-
"BDUT 0.0000000000e+00-4.085620730e-14 14 782 ",
302+
"BDUT 0.0000000000E+00-4.085620730E-14 14 782 TIME SYSTEM CORR\n",
304303
0.0,
305304
-4.085620730e-14,
306305
782,
@@ -309,7 +308,7 @@ mod test {
309308
TimeScale::UTC,
310309
),
311310
(
312-
"QZUT 5.5879354477e-09 0.000000000e+00 94208 2139 ",
311+
"QZUT 5.5879354477E-09 0.000000000E+00 94208 2139 TIME SYSTEM CORR\n",
313312
5.5879354477e-09,
314313
0.000000000e+00,
315314
2139,
@@ -330,8 +329,7 @@ mod test {
330329
parsed.format_v3(&mut buf).unwrap();
331330

332331
let formatted = buf.into_inner().unwrap().to_ascii_utf8();
333-
// TODO: upgrade to NavFormatter with programmable precision
334-
// assert_eq!(formatted, content);
332+
assert_eq!(formatted, content);
335333

336334
let reparsed = TimeOffset::parse_v3(&formatted)
337335
.unwrap_or_else(|e| panic!("Parse back failed for \"{}\" - {}", formatted, e));
@@ -388,7 +386,7 @@ mod test {
388386
// assert_eq!(line, line_1);
389387
} else if index == 1 {
390388
// assert_eq!(line, line_2);
391-
} else {
389+
} else if index == 3 {
392390
panic!("two lines expected (only)!");
393391
}
394392
}

src/tests/production.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ mod test {
2525
println!("Formatting test passed for \"{}\"", path);
2626

2727
// remove copy
28-
let _ = std::fs::remove_file(tmp_path);
28+
// let _ = std::fs::remove_file(tmp_path);
2929
}
3030

3131
#[test]

src/tests/toolkit/nav.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,16 @@ fn generic_header_comparison(dut: &HeaderFields, model: &HeaderFields) {
124124
for t_offset in dut.time_offsets.iter() {
125125
let mut found = false;
126126
for rhs_t_offset in model.time_offsets.iter() {
127-
if rhs_t_offset == t_offset {
128-
found = true;
127+
if rhs_t_offset.rhs == t_offset.rhs && rhs_t_offset.lhs == t_offset.lhs {
128+
if rhs_t_offset.t_ref == t_offset.t_ref && rhs_t_offset.utc == t_offset.utc {
129+
if (rhs_t_offset.polynomials.0 - t_offset.polynomials.0).abs() < 1E-6 {
130+
if (rhs_t_offset.polynomials.1 - t_offset.polynomials.1).abs() < 1E-6 {
131+
if (rhs_t_offset.polynomials.2 - t_offset.polynomials.2).abs() < 1E-6 {
132+
found = true;
133+
}
134+
}
135+
}
136+
}
129137
}
130138
}
131139

@@ -137,8 +145,16 @@ fn generic_header_comparison(dut: &HeaderFields, model: &HeaderFields) {
137145
for t_offset in model.time_offsets.iter() {
138146
let mut found = false;
139147
for lhs_t_offset in dut.time_offsets.iter() {
140-
if lhs_t_offset == t_offset {
141-
found = true;
148+
if lhs_t_offset.rhs == t_offset.rhs && lhs_t_offset.lhs == t_offset.lhs {
149+
if lhs_t_offset.t_ref == t_offset.t_ref && lhs_t_offset.utc == t_offset.utc {
150+
if (lhs_t_offset.polynomials.0 - t_offset.polynomials.0).abs() < 1E-6 {
151+
if (lhs_t_offset.polynomials.1 - t_offset.polynomials.1).abs() < 1E-6 {
152+
if (lhs_t_offset.polynomials.2 - t_offset.polynomials.2).abs() < 1E-6 {
153+
found = true;
154+
}
155+
}
156+
}
157+
}
142158
}
143159
}
144160

0 commit comments

Comments
 (0)