Skip to content

Commit 70ffad9

Browse files
committed
SP3-a: providing support
- SP3-a is limited to GPS and GPST only Signed-off-by: Guillaume W. Bres <guillaume.bressaix@gmail.com>
1 parent e4d0f8f commit 70ffad9

File tree

6 files changed

+105
-29
lines changed

6 files changed

+105
-29
lines changed

src/dynamics.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,8 @@ mod test {
399399

400400
let t0_gpst = Epoch::from_str("2020-06-25T00:00:00 GPST").unwrap();
401401
let t1_gpst = Epoch::from_str("2020-06-25T00:15:00 GPST").unwrap();
402-
let t2_gpst = Epoch::from_str("2020-06-25T00:30:00 GPST").unwrap();
403402
let tlast_gpst = Epoch::from_str("2020-06-25T23:45:00 GPST").unwrap();
404403

405-
let dynamics = sp3.resolve_dynamics();
406404
let clock_drifts = sp3.resolve_clock_drift();
407405

408406
for (k, v) in clock_drifts.data.iter() {

src/errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ pub enum ParsingError {
6060
#[error("failed to parse MJD")]
6161
Mjd,
6262

63-
#[error("failed to parse sv from \"{0}\"")]
64-
SV(String),
63+
#[error("failed to parse/identify SV")]
64+
SV,
6565

6666
#[error("failed to parse (x, y, or z) coordinates from \"{0}\"")]
6767
Coordinates(String),

src/parsing.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
position::{position_entry, PositionEntry},
1818
prelude::{
1919
Constellation, Epoch, Error, Header, ParsingError, ProductionAttributes, SP3Entry, SP3Key,
20-
TimeScale, SP3, SV,
20+
TimeScale, Version, SP3, SV,
2121
},
2222
velocity::{velocity_entry, VelocityEntry},
2323
};
@@ -148,10 +148,18 @@ impl SP3 {
148148
)));
149149
}
150150

151-
if pc_count == 0 {
152-
header.constellation = Constellation::from_str(line[3..5].trim())?;
153-
timescale = TimeScale::from_str(line[9..12].trim())?;
154-
header.timescale = timescale;
151+
// no need to parse this line, since Rev-A is limited
152+
// to GPS-Only
153+
if header.version == Version::A {
154+
header.constellation = Constellation::GPS;
155+
header.timescale = TimeScale::GPST;
156+
} else {
157+
// Constellation identification needs to pass
158+
if pc_count == 0 {
159+
header.constellation = Constellation::from_str(line[3..5].trim())?;
160+
timescale = TimeScale::from_str(line[9..12].trim())?;
161+
header.timescale = timescale;
162+
}
155163
}
156164

157165
pc_count += 1;
@@ -167,7 +175,7 @@ impl SP3 {
167175
continue;
168176
}
169177

170-
let entry = PositionEntry::from_str(line)?;
178+
let entry = PositionEntry::parse(line, header.version)?;
171179

172180
//TODO : move this into %c config frame
173181
if !vehicles.contains(&entry.sv) {
@@ -227,7 +235,7 @@ impl SP3 {
227235
continue;
228236
}
229237

230-
let entry = VelocityEntry::from_str(line)?;
238+
let entry = VelocityEntry::parse(line, header.version)?;
231239
let (sv, (vel_x_dm_s, vel_y_dm_s, vel_z_dm_s), clk_sub_ns) = entry.to_parts();
232240

233241
let (vel_x_km_s, vel_y_km_s, vel_z_km_s) = (

src/position.rs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
//! Position & Clock data parsing
2-
use crate::ParsingError;
3-
use crate::SV;
2+
use crate::{
3+
errors::ParsingError,
4+
prelude::{Constellation, Version, SV},
5+
};
6+
7+
use std::str::FromStr;
48

59
pub fn position_entry(content: &str) -> bool {
610
content.starts_with('P')
@@ -18,9 +22,8 @@ pub struct PositionEntry {
1822
pub orbit_prediction: bool,
1923
}
2024

21-
impl std::str::FromStr for PositionEntry {
22-
type Err = ParsingError;
23-
fn from_str(line: &str) -> Result<Self, Self::Err> {
25+
impl PositionEntry {
26+
pub fn parse(line: &str, revision: Version) -> Result<Self, ParsingError> {
2427
let line_len = line.len();
2528

2629
let mut clock_event = false;
@@ -30,8 +33,18 @@ impl std::str::FromStr for PositionEntry {
3033

3134
let mut clock_us: Option<f64> = None;
3235

33-
let sv =
34-
SV::from_str(line[1..4].trim()).or(Err(ParsingError::SV(line[1..4].to_string())))?;
36+
let sv = match revision {
37+
Version::A => {
38+
// GPS-Only: constellation might be omitted
39+
let prn = line[2..4].trim().parse::<u8>().or(Err(ParsingError::SV))?;
40+
41+
SV::new(Constellation::GPS, prn)
42+
},
43+
_ => {
44+
// parsing needs to pass
45+
SV::from_str(line[1..4].trim()).or(Err(ParsingError::SV))?
46+
},
47+
};
3548

3649
let x = f64::from_str(line[4..18].trim())
3750
.or(Err(ParsingError::Coordinates(line[4..18].to_string())))?;
@@ -82,12 +95,11 @@ impl std::str::FromStr for PositionEntry {
8295
#[cfg(test)]
8396
mod test {
8497
use super::PositionEntry;
85-
use crate::prelude::SV;
98+
use crate::prelude::{Version, SV};
8699
use std::str::FromStr;
87100

88101
#[test]
89102
fn position_entry_parsing() {
90-
// "PG01 -22335.782004 -14656.280389 -1218.238499 -176.397152 10 9 11 102 EP MP",
91103
for (
92104
content,
93105
sv,
@@ -174,7 +186,7 @@ mod test {
174186
),
175187
] {
176188
let sv = SV::from_str(sv).unwrap();
177-
let entry = PositionEntry::from_str(content).unwrap();
189+
let entry = PositionEntry::parse(content, Version::C).unwrap();
178190
assert_eq!(entry.sv, sv);
179191
assert_eq!(entry.x_km, x_km);
180192
assert_eq!(entry.y_km, y_km);
@@ -194,7 +206,7 @@ mod test {
194206
let content =
195207
"PG01 -22335.782004 -14656.280389 -1218.238499 -176.397152 10 9 11 102 EP MP";
196208

197-
let position = PositionEntry::from_str(content).unwrap_or_else(|e| {
209+
let position = PositionEntry::parse(content, Version::C).unwrap_or_else(|e| {
198210
panic!("Failed to parse predicted state \"{}\": {}", content, e);
199211
});
200212

src/tests/test_pool.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,45 @@ mod test {
140140
assert_eq!(parsed_back, sp3); // TODO
141141
}
142142
}
143+
144+
#[test]
145+
fn rev_a() {
146+
let prefix = PathBuf::new()
147+
.join(env!("CARGO_MANIFEST_DIR"))
148+
.join("data/SP3")
149+
.join("A");
150+
151+
for file in [
152+
// "emr08874.sp3",
153+
"p0NGA237351",
154+
"p1NGA237361",
155+
"p2NGA237401",
156+
"p3NGA237411",
157+
"p4NGA237421",
158+
"p5NGA237431",
159+
"p6NGA237441",
160+
"p7NGA237451",
161+
"p8NGA237461",
162+
// "sio06492.sp3",
163+
] {
164+
let file_path = prefix.clone().join(file);
165+
println!("Parsing file \"{}\"", file_path.to_string_lossy());
166+
167+
let sp3 = SP3::from_file(&file_path).unwrap_or_else(|e| {
168+
panic!("failed to parse data/A/{}: {}", file, e);
169+
});
170+
171+
// dump
172+
sp3.to_file("test1.txt").unwrap_or_else(|e| {
173+
panic!("Failed to dump data/A/{}: {}", file, e);
174+
});
175+
176+
// parse back
177+
let _ = SP3::from_file("test1.txt").unwrap_or_else(|e| {
178+
panic!("Failed to parse dumped data/C/{}: {}", file, e);
179+
});
180+
181+
// assert_eq!(parsed_back, sp3); // TODO
182+
}
183+
}
143184
}

src/velocity.rs

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
//! Velocity entry parsing
2-
use crate::ParsingError;
3-
use crate::SV;
2+
use crate::{
3+
errors::ParsingError,
4+
prelude::{Constellation, Version, SV},
5+
};
6+
7+
use std::str::FromStr;
48

59
pub fn velocity_entry(content: &str) -> bool {
610
content.starts_with('V')
@@ -12,16 +16,29 @@ pub struct VelocityEntry {
1216
clock: Option<f64>,
1317
}
1418

15-
impl std::str::FromStr for VelocityEntry {
16-
type Err = ParsingError;
17-
fn from_str(line: &str) -> Result<Self, Self::Err> {
19+
impl VelocityEntry {
20+
pub fn parse(line: &str, revision: Version) -> Result<Self, ParsingError> {
1821
let mut clock: Option<f64> = None;
19-
let sv =
20-
SV::from_str(line[1..4].trim()).or(Err(ParsingError::SV(line[1..4].to_string())))?;
22+
23+
let sv = match revision {
24+
Version::A => {
25+
// GPS-Only: constellation might be omitted
26+
let prn = line[2..4].trim().parse::<u8>().or(Err(ParsingError::SV))?;
27+
28+
SV::new(Constellation::GPS, prn)
29+
},
30+
_ => {
31+
// parsing needs to pass
32+
SV::from_str(line[1..4].trim()).or(Err(ParsingError::SV))?
33+
},
34+
};
35+
2136
let x = f64::from_str(line[4..18].trim())
2237
.or(Err(ParsingError::Coordinates(line[4..18].to_string())))?;
38+
2339
let y = f64::from_str(line[18..32].trim())
2440
.or(Err(ParsingError::Coordinates(line[18..32].to_string())))?;
41+
2542
let z = f64::from_str(line[32..46].trim())
2643
.or(Err(ParsingError::Coordinates(line[32..46].to_string())))?;
2744

0 commit comments

Comments
 (0)