From 3214145704e3e8d93d544bc79384db257d211d3e Mon Sep 17 00:00:00 2001 From: ElouanPETEREAU Date: Fri, 17 Nov 2023 13:47:53 +0100 Subject: [PATCH 1/7] Add a basic CI --- .github/workflows/ci_no_std.yml | 67 +++++++++++++++++++++++++++++++++ .github/workflows/ci_std.yml | 65 ++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 .github/workflows/ci_no_std.yml create mode 100644 .github/workflows/ci_std.yml diff --git a/.github/workflows/ci_no_std.yml b/.github/workflows/ci_no_std.yml new file mode 100644 index 0000000..901fb86 --- /dev/null +++ b/.github/workflows/ci_no_std.yml @@ -0,0 +1,67 @@ +name: no-std check +on: [push] + +jobs: + format_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all --check + lib: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: --no-default-features --features libm -- -D warnings + - uses: actions-rs/cargo@v1 + with: + command: build + args: --no-default-features --features libm + + tests: + needs: lib + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: --tests --no-default-features --features libm -- -D warnings + - uses: actions-rs/cargo@v1 + with: + command: test + args: --no-default-features --features libm + + examples: + needs: lib + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: --examples --no-default-features --features libm -- -D warnings diff --git a/.github/workflows/ci_std.yml b/.github/workflows/ci_std.yml new file mode 100644 index 0000000..a712bac --- /dev/null +++ b/.github/workflows/ci_std.yml @@ -0,0 +1,65 @@ +name: std check +on: [push] + +jobs: + format_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all --check + lib: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: -- -D warnings + - uses: actions-rs/cargo@v1 + with: + command: build + + tests: + needs: lib + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: --tests -- -D warnings + - uses: actions-rs/cargo@v1 + with: + command: test + + examples: + needs: lib + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: --examples -- -D warnings From d957e3faa2dbe65ce8221175824011b0933c83ec Mon Sep 17 00:00:00 2001 From: ElouanPETEREAU Date: Fri, 17 Nov 2023 16:01:51 +0100 Subject: [PATCH 2/7] Fix test warnings --- src/tle.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tle.rs b/src/tle.rs index 3208726..c1ae8e2 100644 --- a/src/tle.rs +++ b/src/tle.rs @@ -1042,7 +1042,7 @@ mod tests { chrono::NaiveTime::from_num_seconds_from_midnight_opt(4747, 402656000).unwrap() ) ); - assert_eq_f64(elements.epoch(), 20.527186712635181); + assert_eq_f64(elements.epoch(), 20.527_186_712_635_18); assert_eq_f64( elements.epoch_afspc_compatibility_mode(), 20.527186712635135, @@ -1217,7 +1217,7 @@ mod tests { assert_eq_f64(elements.epoch(), 8.720103559972621); assert_eq_f64( elements.epoch_afspc_compatibility_mode(), - 8.7201035599722125, + 8.720_103_559_972_213, ); assert_eq_f64(elements.mean_motion_dot, -0.00002182); assert_eq_f64(elements.mean_motion_ddot, 0.0); @@ -1249,7 +1249,7 @@ mod tests { chrono::NaiveTime::from_num_seconds_from_midnight_opt(25600, 136832000).unwrap() ) ); - assert_eq_f64(elements.epoch(), -19.373589875756331); + assert_eq_f64(elements.epoch(), -19.373_589_875_756_33); assert_eq_f64( elements.epoch_afspc_compatibility_mode(), -19.373589875756632, From da0c21702e2c14c2e412978724370909360fccd7 Mon Sep 17 00:00:00 2001 From: ElouanPETEREAU Date: Fri, 17 Nov 2023 16:38:50 +0100 Subject: [PATCH 3/7] Fix rem euclid error for no std crates --- src/deep_space.rs | 18 ++++++++---------- src/model.rs | 46 ++++++++++++++++++++++------------------------ 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/src/deep_space.rs b/src/deep_space.rs index fa7ff94..1ff5c48 100644 --- a/src/deep_space.rs +++ b/src/deep_space.rs @@ -744,16 +744,14 @@ impl propagator::Constants { + inclination.cos() * (p22 % (2.0 * core::f64::consts::PI) - right_ascension) - (solar_delta_inclination + lunar_delta_inclination) * if afspc_compatibility_mode { - p22.rem_euclid({ - #[cfg(feature = "std")] - { - 2.0 * core::f64::consts::PI - } - #[cfg(not(feature = "std"))] - { - &(2.0 * core::f64::consts::PI) - } - }) + #[cfg(feature = "std")] + { + p22.rem_euclid(2.0 * core::f64::consts::PI) + } + #[cfg(not(feature = "std"))] + { + Euclid::rem_euclid(&p22, &(2.0 * core::f64::consts::PI)) + } } else { p22 % (2.0 * core::f64::consts::PI) } diff --git a/src/model.rs b/src/model.rs index 108b7b5..5dbe8d9 100644 --- a/src/model.rs +++ b/src/model.rs @@ -64,22 +64,21 @@ pub fn iau_epoch_to_sidereal_time(epoch: f64) -> f64 { // θ₀ = ¹/₂₄₀ (π / 180) (- 6.2 × 10⁻⁶ c₂₀₀₀³ + 0.093104 c₂₀₀₀² // + (876600 × 3600 + 8640184.812866) c₂₀₀₀ + 67310.54841) mod 2π - ((-6.2e-6 * c2000.powi(3) + let theta = (-6.2e-6 * c2000.powi(3) + 0.093104 * c2000.powi(2) + (876600.0 * 3600.0 + 8640184.812866) * c2000 + 67310.54841) * (core::f64::consts::PI / 180.0) - / 240.0) - .rem_euclid({ - #[cfg(feature = "std")] - { - 2.0 * core::f64::consts::PI - } - #[cfg(not(feature = "std"))] - { - &(2.0 * core::f64::consts::PI) - } - }) + / 240.0; + + #[cfg(feature = "std")] + { + theta.rem_euclid(2.0 * core::f64::consts::PI) + } + #[cfg(not(feature = "std"))] + { + Euclid::rem_euclid(&theta, &(2.0 * core::f64::consts::PI)) + } } /// Converts an epoch to sidereal time using the AFSPC expression @@ -97,19 +96,18 @@ pub fn afspc_epoch_to_sidereal_time(epoch: f64) -> f64 { // + (1.72027916940703639 × 10⁻² + 2π) (t₁₉₇₀ - ⌊t₁₉₇₀ + 10⁻⁸⌋) // + 5.07551419432269442 × 10⁻¹⁵ t₁₉₇₀² mod 2π #[allow(clippy::excessive_precision)] - (1.7321343856509374 + let theta = 1.7321343856509374 + 1.72027916940703639e-2 * (d1970 + 1.0e-8).floor() + (1.72027916940703639e-2 + 2.0 * core::f64::consts::PI) * (d1970 - (d1970 + 1.0e-8).floor()) - + d1970.powi(2) * 5.07551419432269442e-15) - .rem_euclid({ - #[cfg(feature = "std")] - { - 2.0 * core::f64::consts::PI - } - #[cfg(not(feature = "std"))] - { - &(2.0 * core::f64::consts::PI) - } - }) + + d1970.powi(2) * 5.07551419432269442e-15; + + #[cfg(feature = "std")] + { + theta.rem_euclid(2.0 * core::f64::consts::PI) + } + #[cfg(not(feature = "std"))] + { + Euclid::rem_euclid(&theta, &(2.0 * core::f64::consts::PI)) + } } From f9e13938d1b99ef5c11ee6136633534f6dec5376 Mon Sep 17 00:00:00 2001 From: ElouanPETEREAU Date: Fri, 17 Nov 2023 17:40:46 +0100 Subject: [PATCH 4/7] Make tests & examples build with and without std --- Cargo.toml | 23 ++++++++++++++++------- src/tle.rs | 9 ++++++++- tests/propagate.rs | 20 +++++++++++++------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index debe7c4..ab7fcd1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,16 +21,19 @@ keywords = ["SGP4", "SDP4", "TLE", "OMM"] edition = "2021" [dependencies] -anyhow = {version = "1.0", default-features = false, optional = true} -chrono = {version = "0.4.31", default-features = false} -serde = {version = "1.0", default-features = false, optional = true} -serde_json = {version = "1.0", default-features = false, optional = true} -num-traits = {version = "0.2.17", default-features = false, optional = true} +anyhow = { version = "1.0", default-features = false, optional = true } +chrono = { version = "0.4.31", default-features = false } +serde = { version = "1.0", default-features = false, optional = true } +serde_json = { version = "1.0", default-features = false, optional = true } +num-traits = { version = "0.2.17", default-features = false, optional = true } [dev-dependencies] criterion = "0.5.1" toml = "0.8.8" -ureq = {version = "2.8", features = ["json"]} +ureq = { version = "2.8", features = ["json"] } +serde_json = { version = "1.0", default-features = false } +serde = { version = "1.0", default-features = false } +anyhow = { version = "1.0", default-features = false } [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] @@ -38,7 +41,13 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = ["alloc", "serde", "std"] alloc = ["anyhow"] -serde = ["alloc", "chrono/serde", "serde/alloc", "serde/derive", "serde_json/alloc"] +serde = [ + "alloc", + "chrono/serde", + "serde/alloc", + "serde/derive", + "serde_json/alloc", +] std = ["alloc", "anyhow/std", "chrono/std", "serde?/std", "serde_json?/std"] libm = ["num-traits/libm"] diff --git a/src/tle.rs b/src/tle.rs index c1ae8e2..bb11bf9 100644 --- a/src/tle.rs +++ b/src/tle.rs @@ -991,6 +991,7 @@ pub fn parse_3les(tles: &str) -> core::result::Result, mod tests { use super::*; + #[cfg(feature = "serde")] fn assert_eq_f64(first: f64, second: f64) { if second == 0.0 { assert_eq!(first, 0.0); @@ -1063,6 +1064,7 @@ mod tests { } #[test] + #[cfg(feature = "alloc")] fn test_from_space_track_omm() -> anyhow::Result<()> { let elements: Elements = serde_json::from_str( r#"{"CCSDS_OMM_VERS":"2.0", @@ -1144,6 +1146,7 @@ mod tests { } #[test] + #[cfg(feature = "alloc")] fn test_from_celestrak_omms() -> anyhow::Result<()> { let elements_vec: Vec = serde_json::from_str( r#"[{ @@ -1189,12 +1192,14 @@ mod tests { } #[test] + #[cfg(feature = "alloc")] fn test_from_tle() -> core::result::Result<(), Error> { let elements = Elements::from_tle( - Some("ISS (ZARYA)".to_owned()), + Some("ISS (ZARYA)".into()), "1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927".as_bytes(), "2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537".as_bytes(), )?; + match elements.object_name.as_ref() { Some(object_name) => assert_eq!(object_name, "ISS (ZARYA)"), None => panic!(), @@ -1270,6 +1275,7 @@ mod tests { } #[test] + #[cfg(feature = "alloc")] fn test_parse_2les() -> core::result::Result<(), Error> { let elements_vec = parse_2les( "1 25544U 98067A 20194.88612269 -.00002218 00000-0 -31515-4 0 9992\n\ @@ -1282,6 +1288,7 @@ mod tests { } #[test] + #[cfg(feature = "alloc")] fn test_parse_3les() -> core::result::Result<(), Error> { let elements_vec = parse_3les( "ISS (ZARYA)\n\ diff --git a/tests/propagate.rs b/tests/propagate.rs index dd1ec58..9d557be 100644 --- a/tests/propagate.rs +++ b/tests/propagate.rs @@ -6,12 +6,17 @@ use test_cases::*; fn propagate() -> anyhow::Result<()> { let test_cases: TestCases = toml::from_str(include_str!("../test_cases.toml")).unwrap(); for test_case in test_cases.list.iter() { - let constants = - sgp4::Constants::from_elements_afspc_compatibility_mode(&sgp4::Elements::from_tle( - None, - test_case.line1.as_bytes(), - test_case.line2.as_bytes(), - )?)?; + #[cfg(feature = "alloc")] + let element = + sgp4::Elements::from_tle(None, test_case.line1.as_bytes(), test_case.line2.as_bytes())?; + + #[cfg(not(feature = "alloc"))] + let element = + sgp4::Elements::from_tle(test_case.line1.as_bytes(), test_case.line2.as_bytes()) + .map_err(|error| anyhow::anyhow!("{error}"))?; + + let constants = sgp4::Constants::from_elements_afspc_compatibility_mode(&element) + .map_err(|error| anyhow::anyhow!("{error}"))?; for state in &test_case.states { match state { State::Ok { @@ -21,7 +26,8 @@ fn propagate() -> anyhow::Result<()> { .. } => { let prediction = constants - .propagate_afspc_compatibility_mode(sgp4::MinutesSinceEpoch(*time))?; + .propagate_afspc_compatibility_mode(sgp4::MinutesSinceEpoch(*time)) + .map_err(|error| anyhow::anyhow!("{error}"))?; for index in 0..3 { assert!((position[index] - prediction.position[index]).abs() < 1.0e-6); assert!((velocity[index] - prediction.velocity[index]).abs() < 1.0e-9); From 86f49acca02ea8c2046f2ca46d979c5dba6e1af3 Mon Sep 17 00:00:00 2001 From: ElouanPETEREAU Date: Fri, 17 Nov 2023 17:42:51 +0100 Subject: [PATCH 5/7] Remove clippy from no_std tests and examples --- .github/workflows/ci_no_std.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci_no_std.yml b/.github/workflows/ci_no_std.yml index 901fb86..adf2a1d 100644 --- a/.github/workflows/ci_no_std.yml +++ b/.github/workflows/ci_no_std.yml @@ -43,10 +43,6 @@ jobs: profile: minimal toolchain: stable override: true - - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --tests --no-default-features --features libm -- -D warnings - uses: actions-rs/cargo@v1 with: command: test @@ -63,5 +59,5 @@ jobs: override: true - uses: actions-rs/cargo@v1 with: - command: clippy - args: --examples --no-default-features --features libm -- -D warnings + command: check + args: --examples --no-default-features --features libm From ec1ed5fa121408e974ec2671d798337fe39d4d68 Mon Sep 17 00:00:00 2001 From: Elouan Petereau Date: Sun, 19 Nov 2023 13:42:44 +0100 Subject: [PATCH 6/7] Remove examples from nostd no_std CI jobs --- .github/workflows/ci_no_std.yml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/.github/workflows/ci_no_std.yml b/.github/workflows/ci_no_std.yml index adf2a1d..8a60045 100644 --- a/.github/workflows/ci_no_std.yml +++ b/.github/workflows/ci_no_std.yml @@ -46,18 +46,4 @@ jobs: - uses: actions-rs/cargo@v1 with: command: test - args: --no-default-features --features libm - - examples: - needs: lib - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - uses: actions-rs/cargo@v1 - with: - command: check - args: --examples --no-default-features --features libm + args: --tests --no-default-features --features libm \ No newline at end of file From c38b5f7ef75d36fe3f5582ecb2051cec8cf69c0b Mon Sep 17 00:00:00 2001 From: Elouan Petereau Date: Sun, 19 Nov 2023 14:10:50 +0100 Subject: [PATCH 7/7] Improve no_std tests support --- .github/workflows/ci_no_std.yml | 2 +- src/tle.rs | 11 +++++++---- tests/propagate.rs | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci_no_std.yml b/.github/workflows/ci_no_std.yml index 8a60045..8091d31 100644 --- a/.github/workflows/ci_no_std.yml +++ b/.github/workflows/ci_no_std.yml @@ -46,4 +46,4 @@ jobs: - uses: actions-rs/cargo@v1 with: command: test - args: --tests --no-default-features --features libm \ No newline at end of file + args: --tests --no-default-features --features libm --features serde --features alloc \ No newline at end of file diff --git a/src/tle.rs b/src/tle.rs index bb11bf9..cefe51b 100644 --- a/src/tle.rs +++ b/src/tle.rs @@ -1023,7 +1023,8 @@ mod tests { "MEAN_MOTION_DOT": 0.00289036, "MEAN_MOTION_DDOT": 0 }"#, - )?; + ) + .map_err(|error| anyhow::anyhow!("{error}"))?; match elements.object_name.as_ref() { Some(object_name) => assert_eq!(object_name, "ISS (ZARYA)"), None => panic!(), @@ -1108,7 +1109,8 @@ mod tests { "TLE_LINE1":"1 25544U 98067A 20348.69171878 .00000888 00000-0 24124-4 0 9995", "TLE_LINE2":"2 25544 51.6444 180.2777 0001779 128.5985 350.1361 15.49181153259845" }"#, - )?; + ) + .map_err(|error| anyhow::anyhow!("{error}"))?; match elements.object_name.as_ref() { Some(object_name) => assert_eq!(object_name, "ISS (ZARYA)"), None => panic!(), @@ -1148,7 +1150,7 @@ mod tests { #[test] #[cfg(feature = "alloc")] fn test_from_celestrak_omms() -> anyhow::Result<()> { - let elements_vec: Vec = serde_json::from_str( + let elements_vec: [Elements; 2] = serde_json::from_str( r#"[{ "OBJECT_NAME": "ISS (ZARYA)", "OBJECT_ID": "1998-067A", @@ -1186,7 +1188,8 @@ mod tests { "MEAN_MOTION_DOT": 8.489e-5, "MEAN_MOTION_DDOT": 0 }]"#, - )?; + ) + .map_err(|error| anyhow::anyhow!("{error}"))?; assert_eq!(elements_vec.len(), 2); Ok(()) } diff --git a/tests/propagate.rs b/tests/propagate.rs index 9d557be..4e7c553 100644 --- a/tests/propagate.rs +++ b/tests/propagate.rs @@ -8,7 +8,8 @@ fn propagate() -> anyhow::Result<()> { for test_case in test_cases.list.iter() { #[cfg(feature = "alloc")] let element = - sgp4::Elements::from_tle(None, test_case.line1.as_bytes(), test_case.line2.as_bytes())?; + sgp4::Elements::from_tle(None, test_case.line1.as_bytes(), test_case.line2.as_bytes()) + .map_err(|error| anyhow::anyhow!("{error}"))?; #[cfg(not(feature = "alloc"))] let element =