Skip to content

Commit 0dede89

Browse files
Merge pull request #391 from nyx-space/cleanup/gh-390
Cleaning up Nyx in prep for 2.0.0
2 parents cc00ae3 + 6eecf3a commit 0dede89

File tree

97 files changed

+1270
-5733
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+1270
-5733
lines changed

Cargo.toml

+12-21
Original file line numberDiff line numberDiff line change
@@ -32,65 +32,56 @@ exclude = [
3232

3333
[badges]
3434
maintenance = { status = "actively-developed" }
35-
gitlab = { repository = "nyx-space/nyx", branch = "master" }
35+
github = { repository = "nyx-space/nyx", branch = "master" }
3636

3737
[dependencies]
3838
nalgebra = "0.33"
3939
log = "0.4"
4040
hifitime = "4.0.0"
41-
anise = "0.5.0"
41+
anise = "0.5.2"
4242
flate2 = { version = "1.0", features = [
4343
"rust_backend",
4444
], default-features = false }
4545
serde = "1.0"
4646
serde_derive = "1.0"
47-
csv = "1"
4847
hyperdual = "1.3.0"
49-
bytes = "1.0"
5048
rand = "0.8"
5149
rand_distr = "0.4"
5250
regex = "1.5"
5351
rayon = "1.6"
54-
lazy_static = "1.4.0"
5552
approx = "0.5"
5653
rand_pcg = "0.3"
57-
indicatif = { version = "0.17", features = ["rayon"] }
54+
indicatif = { version = "0.17", features = ["rayon"], default-features = false }
5855
rstats = "2.0.1"
59-
parquet = { version = "53.0.0", default-features = false, features = [
56+
parquet = { version = "54.0.0", default-features = false, features = [
6057
"arrow",
6158
"zstd",
6259
] }
63-
arrow = "53.0.0"
64-
shadow-rs = { version = "0.36.0", default-features = false }
60+
arrow = "54.0.0"
61+
shadow-rs = { version = "0.37.0", default-features = false }
6562
serde_yml = "0.0.12"
6663
whoami = "1.3.0"
6764
either = { version = "1.8.1", features = ["serde"] }
6865
num = "0.4.0"
6966
enum-iterator = "2.0.0"
70-
getrandom = { version = "0.2", features = ["js"] }
7167
typed-builder = "0.20.0"
7268
snafu = { version = "0.8.3", features = ["backtrace"] }
7369
serde_dhall = "0.12"
74-
indexmap = {version = "2.6.0", features = ["serde"]}
70+
indexmap = { version = "2.6.0", features = ["serde"] }
7571

7672

7773
[dev-dependencies]
78-
polars = { version = "0.43.1", features = ["parquet"] }
74+
polars = { version = "0.45.1", features = ["parquet"] }
7975
rstest = "0.23.0"
8076
pretty_env_logger = "0.5"
8177
toml = "0.8.14"
8278

8379
[build-dependencies]
84-
shadow-rs = "0.36.0"
80+
shadow-rs = "0.37.0"
8581

86-
[features]
87-
default = []
88-
# python = ["pyo3", "pyo3-log", "hifitime/python", "numpy", "pythonize"]
89-
python = []
90-
91-
[lib]
92-
crate-type = ["cdylib", "rlib"]
93-
name = "nyx_space"
82+
# Uncomment to speed up local builds
83+
# [profile.dev.package."*"]
84+
# opt-level = 3
9485

9586
[target.x86_64-unknown-linux-gnu]
9687
# For flamegraph -- https://github.com/flamegraph-rs/flamegraph

README.md

+25-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[**Empowering flight dynamics engineers with open-source software**][website]
44

5-
Nyx is revolutionizing the field of flight dynamics engineering as a powerful, open-source tool for mission design and orbit determination. From trajectory optimization to orbit estimation, Nyx is built for speed, automation, and scalability. It dramatically reduces simulation time compared to commercial products, and integrates seamlessly into automated workflows across various platforms.
5+
Nyx is revolutionizing the field of flight dynamics engineering as a powerful, open-source tool for mission design and orbit determination. From trajectory optimization to orbit estimation, Nyx is built for speed, automation, and scalability.
66

77
**Nyx has proven mission-critical reliability, already contributing to the success of three lunar missions.**
88

@@ -13,6 +13,28 @@ Nyx is revolutionizing the field of flight dynamics engineering as a powerful, o
1313
[![nyx-space on docs.rs][docsrs-image]][docsrs]
1414
[![codecov](https://codecov.io/gh/nyx-space/nyx/graph/badge.svg?token=gEiAvwzwh5)](https://codecov.io/gh/nyx-space/nyx)
1515

16+
# Showcase
17+
18+
[The website has the latest use cases][showcase]
19+
20+
## GEO Low Thrust Orbit Raising & StationKeeping
21+
22+
[Click for description](https://nyxspace.com/nyxspace/showcase/03_geo_analysis/?utm_source=readme-showcase)
23+
24+
[![RAAN, AOP, INC over time](./examples/03_geo_analysis/plots/raise-traj-3d.png)](https://nyxspace.com/nyxspace/showcase/03_geo_analysis/?utm_source=readme-showcase)
25+
26+
## James Webb Space Telescope Monte Carlo Simulation
27+
28+
[Click for description](https://nyxspace.com/nyxspace/showcase/02_jwst_covar_monte_carlo/?utm_source=readme-showcase)
29+
30+
[![RAAN, AOP, INC over time](./examples/02_jwst_covar_monte_carlo/plots/jwst_mc_inc_deg.png)](https://nyxspace.com/nyxspace/showcase/02_jwst_covar_monte_carlo/?utm_source=readme-showcase)
31+
32+
## Orbit Determination of the Lunar Reconnaissance Orbiter
33+
34+
[Click for description](https://nyxspace.com/nyxspace/showcase/04_lro_od/?utm_source=readme-showcase)
35+
36+
[![RAAN, AOP, INC over time](./examples/04_lro_od/plots/doppler-resid.png)](https://nyxspace.com/nyxspace/showcase/04_lro_od/?utm_source=readme-showcase)
37+
1638
# Documentation
1739

1840
The documentation is currently being updated. If you have specific use cases you would like to see documented, please [open a Github issue](https://github.com/nyx-space/nyx/issues/new?assignees=&labels=Documentation&projects=&template=documentation.md&title=) or [use the contact form][contact]
@@ -49,8 +71,10 @@ Nyx is provided under the [AGPLv3 License](./LICENSE). By using this software, y
4971
[contact]: https://7ug5imdtt8v.typeform.com/to/neFvVW3p
5072
[nyxspace-image]: https://img.shields.io/badge/Nyx_Space-Website-orange
5173
[website]: https://nyxspace.com/?utm_source=readme
74+
[showcase]: https://nyxspace.com/nyxspace/showcase/?utm_source=readme
5275

5376
# Author information
77+
5478
> Chris Rabotin is a GNC and flight dynamics engineer with a heavy background in software.
5579
5680
I currently work for Rocket Lab USA as the lead flight dynamics engineer on both Blue Ghost lunar lander missions. -- Find me on [LinkedIn](https://www.linkedin.com/in/chrisrabotin/).

build.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
fn main() -> shadow_rs::SdResult<()> {
2-
shadow_rs::new()
1+
use shadow_rs::ShadowBuilder;
2+
3+
fn main() {
4+
ShadowBuilder::builder()
5+
.build()
6+
.expect("shadow init for nyx_space failed");
37
}

data/tests/config/spacecraft.yaml

+6-4
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ orbit:
88
frame: EME2000
99
epoch: 2018-09-15T00:15:53.098 UTC
1010
srp:
11-
cr: 1.0
11+
coeff_reflectivity:1.0
1212
area_m2: 2.0
1313
drag:
14-
cd: 2.2
14+
coeff_drag: 2.2
1515
area_m2: 0.95
16-
dry_mass_kg: 50.0
17-
fuel_mass_kg: 50.0
16+
mass:
17+
dry_mass_kg: 50.0
18+
prop_mass_kg: 50.0
19+
extra_mass_kg: 0.0
1820
thruster:
1921
thrust_N: 1e-5
2022
isp_s: 300.0

examples/01_orbit_prop/main.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@ use anise::{
1313
use hifitime::{Epoch, Unit};
1414
use log::warn;
1515
use nyx::{
16-
cosmic::{MetaAlmanac, Orbit, SrpConfig},
16+
cosmic::{Mass, MetaAlmanac, Orbit, SRPData},
1717
dynamics::{Harmonics, OrbitalDynamics, SolarPressure, SpacecraftDynamics},
1818
io::{gravity::HarmonicsMem, ExportCfg},
1919
od::GroundStation,
2020
propagators::Propagator,
2121
Spacecraft, State,
2222
};
23-
use polars::{df, series::ChunkCompare};
23+
use polars::{
24+
frame::column::ScalarColumn,
25+
prelude::{df, AnyValue, ChunkCompareIneq, Column, DataType, Scalar},
26+
};
2427

2528
use std::{error::Error, sync::Arc};
2629

@@ -91,10 +94,10 @@ fn main() -> Result<(), Box<dyn Error>> {
9194
// Let's build a cubesat sized spacecraft, with an SRP area of 10 cm^2 and a mass of 9.6 kg.
9295
let sc = Spacecraft::builder()
9396
.orbit(orbit)
94-
.dry_mass_kg(9.60)
95-
.srp(SrpConfig {
97+
.mass(Mass::from_dry_mass(9.60))
98+
.srp(SRPData {
9699
area_m2: 10e-4,
97-
cr: 1.1,
100+
coeff_reflectivity: 1.1,
98101
})
99102
.build();
100103
println!("{sc:x}");
@@ -274,7 +277,13 @@ fn main() -> Result<(), Box<dyn Error>> {
274277
)?;
275278

276279
// Finally, let's see when the spacecraft is visible, assuming 15 degrees minimum elevation.
277-
let mask = aer_df.column("elevation (deg)")?.gt(15.0)?;
280+
let mask = aer_df
281+
.column("elevation (deg)")?
282+
.gt(&Column::Scalar(ScalarColumn::new(
283+
"elevation mask (deg)".into(),
284+
Scalar::new(DataType::Float64, AnyValue::Float64(15.0)),
285+
offset_s.len(),
286+
)))?;
278287
let cubesat_visible = aer_df.filter(&mask)?;
279288

280289
println!("{cubesat_visible}");

examples/02_jwst_covar_monte_carlo/main.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use anise::{
1212
};
1313
use hifitime::{TimeUnits, Unit};
1414
use nyx::{
15-
cosmic::{eclipse::EclipseLocator, Frame, MetaAlmanac, SrpConfig},
15+
cosmic::{eclipse::EclipseLocator, Frame, Mass, MetaAlmanac, SRPData},
1616
dynamics::{guidance::LocalFrame, OrbitalDynamics, SolarPressure, SpacecraftDynamics},
1717
io::ExportCfg,
1818
mc::MonteCarlo,
@@ -62,11 +62,11 @@ fn main() -> Result<(), Box<dyn Error>> {
6262
// SRP Coefficient of reflectivity assumed to be that of Kapton, i.e. 2 - 0.44 = 1.56, table 1 from https://amostech.com/TechnicalPapers/2018/Poster/Bengtson.pdf
6363
let jwst = Spacecraft::builder()
6464
.orbit(jwst_orbit)
65-
.srp(SrpConfig {
65+
.srp(SRPData {
6666
area_m2: 21.197 * 14.162,
67-
cr: 1.56,
67+
coeff_reflectivity: 1.56,
6868
})
69-
.dry_mass_kg(6200.0)
69+
.mass(Mass::from_dry_mass(6200.0))
7070
.build();
7171

7272
// Build up the spacecraft uncertainty builder.

examples/03_geo_analysis/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ To build the following plots, use the `plot_3d_traj.py` script and the `plot_orb
9191

9292
![Orbital elements during orbit raise](./plots/raise-keplerian-oe.png)
9393

94-
In the two follow plots, the colors correspond to the remaining fuel mass, thereby showing the fuel depletion over the orbit raise.
94+
In the two follow plots, the colors correspond to the remaining prop mass, thereby showing the prop depletion over the orbit raise.
9595

9696
![3D traj raise](./plots/raise-traj-3d.png)
9797

@@ -112,7 +112,7 @@ To run the [station keeping Monte Carlo](./stationkeeping.rs) example, just exec
112112
RUST_LOG=info cargo run --example 03_geo_sk --release
113113
```
114114

115-
Over a two week period, this two-ton spacecraft would need roughly 0.8 kg of fuel (if using the _NEXT-STEP_ engine, cf. the comments in the drift analysis code) +/- 0.1 kg for station keeping.
115+
Over a two week period, this two-ton spacecraft would need roughly 0.8 kg of prop (if using the _NEXT-STEP_ engine, cf. the comments in the drift analysis code) +/- 0.1 kg for station keeping.
116116

117117
![Fuel mass](./plots/sk-fuel-mass.png)
118118

@@ -123,4 +123,4 @@ The inclination plot shows when the guidance law turns on, and shows that we mai
123123

124124
### Further analysis
125125

126-
Additional analysis would run this Monte Carlo for longer and with many more spacecraft (upward of 100), and crucially ensure that the Ruggiero guidance law bounds correspond to the GEO box. Subsequently, one should implement the Q-Law guidance law for more fuel economy. Finally, the analysis should also include a variation on the tightness of the box, especially if the vehicle is equipped with a variable thrust engine as one may wish to drift less out of the SK box and keep the engine at a lower thrust level, or vice versa.
126+
Additional analysis would run this Monte Carlo for longer and with many more spacecraft (upward of 100), and crucially ensure that the Ruggiero guidance law bounds correspond to the GEO box. Subsequently, one should implement the Q-Law guidance law for more prop economy. Finally, the analysis should also include a variation on the tightness of the box, especially if the vehicle is equipped with a variable thrust engine as one may wish to drift less out of the SK box and keep the engine at a lower thrust level, or vice versa.

examples/03_geo_analysis/drift.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use anise::{
1212
};
1313
use hifitime::{Epoch, Unit};
1414
use nyx::{
15-
cosmic::{eclipse::EclipseLocator, MetaAlmanac, Orbit, SrpConfig},
15+
cosmic::{eclipse::EclipseLocator, Mass, MetaAlmanac, Orbit, SRPData},
1616
dynamics::{Harmonics, OrbitalDynamics, SolarPressure, SpacecraftDynamics},
1717
io::{gravity::HarmonicsMem, ExportCfg},
1818
propagators::Propagator,
@@ -61,10 +61,10 @@ fn main() -> Result<(), Box<dyn Error>> {
6161
// Let's build a cubesat sized spacecraft, with an SRP area of 10 cm^2 and a mass of 9.6 kg.
6262
let sc = Spacecraft::builder()
6363
.orbit(orbit)
64-
.dry_mass_kg(9.60)
65-
.srp(SrpConfig {
64+
.mass(Mass::from_dry_mass(9.60))
65+
.srp(SRPData {
6666
area_m2: 10e-4,
67-
cr: 1.1,
67+
coeff_reflectivity: 1.1,
6868
})
6969
.build();
7070
println!("{sc:x}");

examples/03_geo_analysis/plot_3d_traj.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ def build_sphere(size, num_points=500, opacity=1.0):
3737

3838
def plot_traj(
3939
df: pl.DataFrame,
40-
colored_by="fuel_mass (kg)",
41-
color_descr="fuel mass (kg)",
40+
colored_by="prop_mass (kg)",
41+
color_descr="prop mass (kg)",
4242
scale=1.0
4343
):
4444
"""

examples/03_geo_analysis/plot_sk_mc.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"ta (deg)",
1919
"aol (deg)",
2020
"tlong (deg)",
21-
"fuel_mass (kg)",
21+
"prop_mass (kg)",
2222
]
2323

2424
for col in columns:

examples/03_geo_analysis/raise.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use anise::{
1212
};
1313
use hifitime::{Epoch, TimeUnits, Unit};
1414
use nyx::{
15-
cosmic::{eclipse::EclipseLocator, GuidanceMode, MetaAlmanac, Orbit, SrpConfig},
15+
cosmic::{eclipse::EclipseLocator, GuidanceMode, Mass, MetaAlmanac, Orbit, SRPData},
1616
dynamics::{
1717
guidance::{GuidanceLaw, Ruggiero, Thruster},
1818
Harmonics, OrbitalDynamics, SolarPressure, SpacecraftDynamics,
@@ -51,9 +51,8 @@ fn main() -> Result<(), Box<dyn Error>> {
5151

5252
let sc = Spacecraft::builder()
5353
.orbit(orbit)
54-
.dry_mass_kg(1000.0) // 1000 kg of dry mass
55-
.fuel_mass_kg(1000.0) // 1000 kg of fuel, totalling 2.0 tons
56-
.srp(SrpConfig::from_area(3.0 * 6.0)) // Assuming 1 kW/m^2 or 18 kW, giving a margin of 4.35 kW for on-propulsion consumption
54+
.mass(Mass::from_dry_and_prop_masses(1000.0, 1000.0)) // 1000 kg of dry mass and prop, totalling 2.0 tons
55+
.srp(SRPData::from_area(3.0 * 6.0)) // Assuming 1 kW/m^2 or 18 kW, giving a margin of 4.35 kW for on-propulsion consumption
5756
.thruster(Thruster {
5857
// "NEXT-STEP" row in Table 2
5958
isp_s: 4435.0,
@@ -125,9 +124,9 @@ fn main() -> Result<(), Box<dyn Error>> {
125124
.with(sc, almanac.clone())
126125
.for_duration_with_traj(prop_time)?;
127126

128-
let fuel_usage = sc.fuel_mass_kg - final_state.fuel_mass_kg;
127+
let prop_usage = sc.mass.prop_mass_kg - final_state.mass.prop_mass_kg;
129128
println!("{:x}", final_state.orbit);
130-
println!("fuel usage: {:.3} kg", fuel_usage);
129+
println!("prop usage: {:.3} kg", prop_usage);
131130

132131
// Finally, export the results for analysis, including the penumbra percentage throughout the orbit raise.
133132
traj.to_parquet(

examples/03_geo_analysis/stationkeeping.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use anise::{
1212
};
1313
use hifitime::{Epoch, TimeUnits, Unit};
1414
use nyx::{
15-
cosmic::{eclipse::EclipseLocator, GuidanceMode, MetaAlmanac, Orbit, SrpConfig},
15+
cosmic::{eclipse::EclipseLocator, GuidanceMode, Mass, MetaAlmanac, Orbit, SRPData},
1616
dynamics::{
1717
guidance::{Ruggiero, Thruster},
1818
Harmonics, OrbitalDynamics, SolarPressure, SpacecraftDynamics,
@@ -38,9 +38,8 @@ fn main() -> Result<(), Box<dyn Error>> {
3838

3939
let sc = Spacecraft::builder()
4040
.orbit(orbit)
41-
.dry_mass_kg(1000.0) // 1000 kg of dry mass
42-
.fuel_mass_kg(1000.0) // 1000 kg of fuel, totalling 2.0 tons
43-
.srp(SrpConfig::from_area(3.0 * 6.0)) // Assuming 1 kW/m^2 or 18 kW, giving a margin of 4.35 kW for on-propulsion consumption
41+
.mass(Mass::from_dry_and_prop_masses(1000.0, 1000.0)) // 1000 kg of dry mass and prop, totalling 2.0 tons
42+
.srp(SRPData::from_area(3.0 * 6.0)) // Assuming 1 kW/m^2 or 18 kW, giving a margin of 4.35 kW for on-propulsion consumption
4443
.thruster(Thruster {
4544
// "NEXT-STEP" row in Table 2
4645
isp_s: 4435.0,

examples/04_lro_od/main.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use anise::{
1212
};
1313
use hifitime::{Epoch, TimeUnits, Unit};
1414
use nyx::{
15-
cosmic::{Aberration, Frame, MetaAlmanac, SrpConfig},
15+
cosmic::{Aberration, Frame, Mass, MetaAlmanac, SRPData},
1616
dynamics::{
1717
guidance::LocalFrame, Harmonics, OrbitalDynamics, SolarPressure, SpacecraftDynamics,
1818
},
@@ -77,12 +77,11 @@ fn main() -> Result<(), Box<dyn Error>> {
7777

7878
// To build the trajectory we need to provide a spacecraft template.
7979
let sc_template = Spacecraft::builder()
80-
.dry_mass_kg(1018.0) // Launch masses
81-
.fuel_mass_kg(900.0)
82-
.srp(SrpConfig {
80+
.mass(Mass::from_dry_and_prop_masses(1018.0, 900.0)) // Launch masses
81+
.srp(SRPData {
8382
// SRP configuration is arbitrary, but we will be estimating it anyway.
8483
area_m2: 3.9 * 2.7,
85-
cr: 0.96,
84+
coeff_reflectivity: 0.96,
8685
})
8786
.orbit(Orbit::zero(MOON_J2000)) // Setting a zero orbit here because it's just a template
8887
.build();
@@ -125,7 +124,6 @@ fn main() -> Result<(), Box<dyn Error>> {
125124
// The harmonics must be computed in the body fixed frame.
126125
// We're using the long term prediction of the Moon principal axes frame.
127126
let moon_pa_frame = MOON_PA_FRAME.with_orient(31008);
128-
// let moon_pa_frame = IAU_MOON_FRAME;
129127
let sph_harmonics = Harmonics::from_stor(
130128
almanac.frame_from_uid(moon_pa_frame)?,
131129
HarmonicsMem::from_shadr(&jggrx_meta.uri, 80, 80, true)?,

0 commit comments

Comments
 (0)