Skip to main content

ExportCfgBuilder

Struct ExportCfgBuilder 

Source
pub struct ExportCfgBuilder<TypedBuilderFields = ((), (), (), (), (), ())> { /* private fields */ }
Expand description

Builder for ExportCfg instances.

See ExportCfg::builder() for more info.

Implementations§

Source§

impl<__start_epoch, __end_epoch, __step, __metadata, __timestamp> ExportCfgBuilder<((), __start_epoch, __end_epoch, __step, __metadata, __timestamp)>

Source

pub fn fields( self, fields: Vec<StateParameter>, ) -> ExportCfgBuilder<((Option<Vec<StateParameter>>,), __start_epoch, __end_epoch, __step, __metadata, __timestamp)>

Fields to export, if unset, defaults to all possible fields.

Source§

impl<__fields, __end_epoch, __step, __metadata, __timestamp> ExportCfgBuilder<(__fields, (), __end_epoch, __step, __metadata, __timestamp)>

Source

pub fn start_epoch( self, start_epoch: Epoch, ) -> ExportCfgBuilder<(__fields, (Option<Epoch>,), __end_epoch, __step, __metadata, __timestamp)>

Start epoch to export, defaults to the start of the trajectory

Source§

impl<__fields, __start_epoch, __step, __metadata, __timestamp> ExportCfgBuilder<(__fields, __start_epoch, (), __step, __metadata, __timestamp)>

Source

pub fn end_epoch( self, end_epoch: Epoch, ) -> ExportCfgBuilder<(__fields, __start_epoch, (Option<Epoch>,), __step, __metadata, __timestamp)>

End epoch to export, defaults to the end of the trajectory

Source§

impl<__fields, __start_epoch, __end_epoch, __metadata, __timestamp> ExportCfgBuilder<(__fields, __start_epoch, __end_epoch, (), __metadata, __timestamp)>

Source

pub fn step( self, step: Duration, ) -> ExportCfgBuilder<(__fields, __start_epoch, __end_epoch, (Option<Duration>,), __metadata, __timestamp)>

An optional step, defaults to every state in the trajectory (which likely isn’t equidistant)

Examples found in repository?
nyx-core/examples/03_geo_analysis/drift.rs (line 160)
26fn main() -> Result<(), Box<dyn Error>> {
27    pel::init();
28    // Dynamics models require planetary constants and ephemerides to be defined.
29    // Let's start by grabbing those by using ANISE's latest MetaAlmanac.
30    // This will automatically download the DE440s planetary ephemeris,
31    // the daily-updated Earth Orientation Parameters, the high fidelity Moon orientation
32    // parameters (for the Moon Mean Earth and Moon Principal Axes frames), and the PCK11
33    // planetary constants kernels.
34    // For details, refer to https://github.com/nyx-space/anise/blob/master/data/latest.dhall.
35    // Note that we place the Almanac into an Arc so we can clone it cheaply and provide read-only
36    // references to many functions.
37    let almanac = Arc::new(MetaAlmanac::latest().map_err(Box::new)?);
38    // Define the orbit epoch
39    let epoch = Epoch::from_gregorian_utc_hms(2024, 2, 29, 12, 13, 14);
40
41    // Define the orbit.
42    // First we need to fetch the Earth J2000 from information from the Almanac.
43    // This allows the frame to include the gravitational parameters and the shape of the Earth,
44    // defined as a tri-axial ellipoid. Note that this shape can be changed manually or in the Almanac
45    // by loading a different set of planetary constants.
46    let earth_j2000 = almanac.frame_info(EARTH_J2000)?;
47
48    // Placing this GEO bird just above Colorado.
49    // In theory, the eccentricity is zero, but in practice, it's about 1e-5 to 1e-6 at best.
50    let orbit = Orbit::try_keplerian(42164.0, 1e-5, 0., 163.0, 75.0, 0.0, epoch, earth_j2000)?;
51    // Print in in Keplerian form.
52    println!("{orbit:x}");
53
54    let state_bf = almanac.transform_to(orbit, IAU_EARTH_FRAME, None)?;
55    let (orig_lat_deg, orig_long_deg, orig_alt_km) = state_bf.latlongalt()?;
56
57    // Nyx is used for high fidelity propagation, not Keplerian propagation as above.
58    // Nyx only propagates Spacecraft at the moment, which allows it to account for acceleration
59    // models such as solar radiation pressure.
60
61    // Let's build a cubesat sized spacecraft, with an SRP area of 10 cm^2 and a mass of 9.6 kg.
62    let sc = Spacecraft::builder()
63        .orbit(orbit)
64        .mass(Mass::from_dry_mass(9.60))
65        .srp(SRPData {
66            area_m2: 10e-4,
67            coeff_reflectivity: 1.1,
68        })
69        .build();
70    println!("{sc:x}");
71
72    // Set up the spacecraft dynamics.
73
74    // Specify that the orbital dynamics must account for the graviational pull of the Moon and the Sun.
75    // The gravity of the Earth will also be accounted for since the spaceraft in an Earth orbit.
76    let mut orbital_dyn = OrbitalDynamics::point_masses(vec![MOON, SUN]);
77
78    // We want to include the spherical harmonics, so let's download the gravitational data from the Nyx Cloud.
79    // We're using the JGM3 model here, which is the default in GMAT.
80    let mut jgm3_meta = MetaFile {
81        uri: "http://public-data.nyxspace.com/nyx/models/JGM3.cof.gz".to_string(),
82        crc32: Some(0xF446F027), // Specifying the CRC32 avoids redownloading it if it's cached.
83    };
84    // And let's download it if we don't have it yet.
85    jgm3_meta.process(true)?;
86
87    // Build the spherical harmonics.
88    // The harmonics must be computed in the body fixed frame.
89    // We're using the long term prediction of the Earth centered Earth fixed frame, IAU Earth.
90    let harmonics_21x21 = GravityField::new(
91        GravityFieldData::from_cof(
92            &jgm3_meta.uri,
93            21,
94            21,
95            true,
96            almanac.frame_info(IAU_EARTH_FRAME)?,
97        )
98        .unwrap(),
99    );
100
101    // Include the spherical harmonics into the orbital dynamics.
102    orbital_dyn.accel_models.push(harmonics_21x21);
103
104    // We define the solar radiation pressure, using the default solar flux and accounting only
105    // for the eclipsing caused by the Earth and Moon.
106    let srp_dyn = SolarPressure::new(vec![EARTH_J2000, MOON_J2000], &almanac)?;
107
108    // Finalize setting up the dynamics, specifying the force models (orbital_dyn) separately from the
109    // acceleration models (SRP in this case). Use `from_models` to specify multiple accel models.
110    let dynamics = SpacecraftDynamics::from_model(orbital_dyn, srp_dyn);
111
112    println!("{dynamics}");
113
114    // Finally, let's propagate this orbit to the same epoch as above.
115    // The first returned value is the spacecraft state at the final epoch.
116    // The second value is the full trajectory where the step size is variable step used by the propagator.
117    let (future_sc, trajectory) = Propagator::default(dynamics)
118        .with(sc, almanac.clone())
119        .until_epoch_with_traj(epoch + Unit::Century * 0.03)?;
120
121    println!("=== High fidelity propagation ===");
122    println!(
123        "SMA changed by {:.3} km",
124        orbit.sma_km()? - future_sc.orbit.sma_km()?
125    );
126    println!(
127        "ECC changed by {:.6}",
128        orbit.ecc()? - future_sc.orbit.ecc()?
129    );
130    println!(
131        "INC changed by {:.3e} deg",
132        orbit.inc_deg()? - future_sc.orbit.inc_deg()?
133    );
134    println!(
135        "RAAN changed by {:.3} deg",
136        orbit.raan_deg()? - future_sc.orbit.raan_deg()?
137    );
138    println!(
139        "AOP changed by {:.3} deg",
140        orbit.aop_deg()? - future_sc.orbit.aop_deg()?
141    );
142    println!(
143        "TA changed by {:.3} deg",
144        orbit.ta_deg()? - future_sc.orbit.ta_deg()?
145    );
146
147    // We also have access to the full trajectory throughout the propagation.
148    println!("{trajectory}");
149
150    println!("Spacecraft params after 3 years without active control:\n{future_sc:x}");
151
152    // With the trajectory, let's build a few data products.
153
154    // 1. Export the trajectory as a parquet file, which includes the Keplerian orbital elements.
155
156    let analysis_step = Unit::Minute * 5;
157
158    trajectory.to_parquet(
159        "./03_geo_hf_prop.parquet",
160        ExportCfg::builder().step(analysis_step).build(),
161    )?;
162
163    // 2. Compute the latitude, longitude, and altitude throughout the trajectory by rotating the spacecraft position into the Earth body fixed frame.
164
165    // We iterate over the trajectory, grabbing a state every two minutes.
166    let mut offset_s = vec![];
167    let mut epoch_str = vec![];
168    let mut longitude_deg = vec![];
169    let mut latitude_deg = vec![];
170    let mut altitude_km = vec![];
171
172    for state in trajectory.every(analysis_step) {
173        // Convert the GEO bird state into the body fixed frame, and keep track of its latitude, longitude, and altitude.
174        // These define the GEO stationkeeping box.
175
176        let this_epoch = state.epoch();
177
178        offset_s.push((this_epoch - orbit.epoch).to_seconds());
179        epoch_str.push(this_epoch.to_isoformat());
180
181        let state_bf = almanac.transform_to(state.orbit, IAU_EARTH_FRAME, None)?;
182        let (lat_deg, long_deg, alt_km) = state_bf.latlongalt()?;
183        longitude_deg.push(long_deg);
184        latitude_deg.push(lat_deg);
185        altitude_km.push(alt_km);
186    }
187
188    println!(
189        "Longitude changed by {:.3} deg -- Box is 0.1 deg E-W",
190        orig_long_deg - longitude_deg.last().unwrap()
191    );
192
193    println!(
194        "Latitude changed by {:.3} deg -- Box is 0.05 deg N-S",
195        orig_lat_deg - latitude_deg.last().unwrap()
196    );
197
198    println!(
199        "Altitude changed by {:.3} km -- Box is 30 km",
200        orig_alt_km - altitude_km.last().unwrap()
201    );
202
203    // Build the station keeping data frame.
204    let mut sk_df = df!(
205        "Offset (s)" => offset_s.clone(),
206        "Epoch (UTC)" => epoch_str.clone(),
207        "Longitude E-W (deg)" => longitude_deg,
208        "Latitude N-S (deg)" => latitude_deg,
209        "Altitude (km)" => altitude_km,
210
211    )?;
212
213    // Create a file to write the Parquet to
214    let file = File::create("./03_geo_lla.parquet").expect("Could not create file");
215
216    // Create a ParquetWriter and write the DataFrame to the file
217    ParquetWriter::new(file).finish(&mut sk_df)?;
218
219    Ok(())
220}
More examples
Hide additional examples
nyx-core/examples/01_orbit_prop/main.rs (line 192)
30fn main() -> Result<(), Box<dyn Error>> {
31    pel::init();
32    // Dynamics models require planetary constants and ephemerides to be defined.
33    // Let's start by grabbing those by using ANISE's latest MetaAlmanac.
34    // This will automatically download the DE440s planetary ephemeris,
35    // the daily-updated Earth Orientation Parameters, the high fidelity Moon orientation
36    // parameters (for the Moon Mean Earth and Moon Principal Axes frames), and the PCK11
37    // planetary constants kernels.
38    // For details, refer to https://github.com/nyx-space/anise/blob/master/data/latest.dhall.
39    // Note that we place the Almanac into an Arc so we can clone it cheaply and provide read-only
40    // references to many functions.
41    let almanac = Arc::new(MetaAlmanac::latest().map_err(Box::new)?);
42    // Define the orbit epoch
43    let epoch = Epoch::from_gregorian_utc_hms(2024, 2, 29, 12, 13, 14);
44
45    // Define the orbit.
46    // First we need to fetch the Earth J2000 from information from the Almanac.
47    // This allows the frame to include the gravitational parameters and the shape of the Earth,
48    // defined as a tri-axial ellipoid. Note that this shape can be changed manually or in the Almanac
49    // by loading a different set of planetary constants.
50    let earth_j2000 = almanac.frame_info(EARTH_J2000)?;
51
52    let orbit =
53        Orbit::try_keplerian_altitude(300.0, 0.015, 68.5, 65.2, 75.0, 0.0, epoch, earth_j2000)?;
54    // Print in in Keplerian form.
55    println!("{orbit:x}");
56
57    // There are two ways to propagate an orbit. We can make a quick approximation assuming only two-body
58    // motion. This is a useful first order approximation but it isn't used in real-world applications.
59
60    // This approach is a feature of ANISE.
61    let future_orbit_tb = orbit.at_epoch(epoch + Unit::Day * 3)?;
62    println!("{future_orbit_tb:x}");
63
64    // Two body propagation relies solely on Kepler's laws, so only the true anomaly will change.
65    println!(
66        "SMA changed by {:.3e} km",
67        orbit.sma_km()? - future_orbit_tb.sma_km()?
68    );
69    println!(
70        "ECC changed by {:.3e}",
71        orbit.ecc()? - future_orbit_tb.ecc()?
72    );
73    println!(
74        "INC changed by {:.3e} deg",
75        orbit.inc_deg()? - future_orbit_tb.inc_deg()?
76    );
77    println!(
78        "RAAN changed by {:.3e} deg",
79        orbit.raan_deg()? - future_orbit_tb.raan_deg()?
80    );
81    println!(
82        "AOP changed by {:.3e} deg",
83        orbit.aop_deg()? - future_orbit_tb.aop_deg()?
84    );
85    println!(
86        "TA changed by {:.3} deg",
87        orbit.ta_deg()? - future_orbit_tb.ta_deg()?
88    );
89
90    // Nyx is used for high fidelity propagation, not Keplerian propagation as above.
91    // Nyx only propagates Spacecraft at the moment, which allows it to account for acceleration
92    // models such as solar radiation pressure.
93
94    // Let's build a cubesat sized spacecraft, with an SRP area of 10 cm^2 and a mass of 9.6 kg.
95    let sc = Spacecraft::builder()
96        .orbit(orbit)
97        .mass(Mass::from_dry_mass(9.60))
98        .srp(SRPData {
99            area_m2: 10e-4,
100            coeff_reflectivity: 1.1,
101        })
102        .build();
103    println!("{sc:x}");
104
105    // Set up the spacecraft dynamics.
106
107    // Specify that the orbital dynamics must account for the graviational pull of the Moon and the Sun.
108    // The gravity of the Earth will also be accounted for since the spaceraft in an Earth orbit.
109    let mut orbital_dyn = OrbitalDynamics::point_masses(vec![MOON, SUN]);
110
111    // We want to include the spherical harmonics, so let's download the gravitational data from the Nyx Cloud.
112    // We're using the JGM3 model here, which is the default in GMAT.
113    let mut jgm3_meta = MetaFile {
114        uri: "http://public-data.nyxspace.com/nyx/models/JGM3.cof.gz".to_string(),
115        crc32: Some(0xF446F027), // Specifying the CRC32 avoids redownloading it if it's cached.
116    };
117    // And let's download it if we don't have it yet.
118    jgm3_meta.process(true)?;
119
120    // Build the spherical harmonics.
121    // The harmonics must be computed in the body fixed frame.
122    // We're using the long term prediction of the Earth centered Earth fixed frame, IAU Earth.
123    let harmonics_21x21 = GravityField::new(
124        GravityFieldData::from_cof(
125            &jgm3_meta.uri,
126            21,
127            21,
128            true,
129            almanac.frame_info(IAU_EARTH_FRAME)?,
130        )
131        .unwrap(),
132    );
133
134    // Include the spherical harmonics into the orbital dynamics.
135    orbital_dyn.accel_models.push(harmonics_21x21);
136
137    // We define the solar radiation pressure, using the default solar flux and accounting only
138    // for the eclipsing caused by the Earth.
139    let srp_dyn = SolarPressure::default_flux(EARTH_J2000, &almanac)?;
140
141    // Finalize setting up the dynamics, specifying the force models (orbital_dyn) separately from the
142    // acceleration models (SRP in this case). Use `from_models` to specify multiple accel models.
143    let dynamics = SpacecraftDynamics::from_model(orbital_dyn, srp_dyn);
144
145    println!("{dynamics}");
146
147    // Finally, let's propagate this orbit to the same epoch as above.
148    // The first returned value is the spacecraft state at the final epoch.
149    // The second value is the full trajectory where the step size is variable step used by the propagator.
150    let (future_sc, trajectory) = Propagator::default(dynamics)
151        .with(sc, almanac.clone())
152        .until_epoch_with_traj(future_orbit_tb.epoch)?;
153
154    println!("=== High fidelity propagation ===");
155    println!(
156        "SMA changed by {:.3} km",
157        orbit.sma_km()? - future_sc.orbit.sma_km()?
158    );
159    println!(
160        "ECC changed by {:.6}",
161        orbit.ecc()? - future_sc.orbit.ecc()?
162    );
163    println!(
164        "INC changed by {:.3e} deg",
165        orbit.inc_deg()? - future_sc.orbit.inc_deg()?
166    );
167    println!(
168        "RAAN changed by {:.3} deg",
169        orbit.raan_deg()? - future_sc.orbit.raan_deg()?
170    );
171    println!(
172        "AOP changed by {:.3} deg",
173        orbit.aop_deg()? - future_sc.orbit.aop_deg()?
174    );
175    println!(
176        "TA changed by {:.3} deg",
177        orbit.ta_deg()? - future_sc.orbit.ta_deg()?
178    );
179
180    // We also have access to the full trajectory throughout the propagation.
181    println!("{trajectory}");
182
183    // With the trajectory, let's build a few data products.
184
185    // 1. Export the trajectory as a CCSDS OEM version 2.0 file and as a parquet file, which includes the Keplerian orbital elements.
186
187    trajectory.to_oem_file(
188        "./01_cubesat_hf_prop.oem",
189        "CUBESAT-ID".to_string(),
190        Some("Nyx Space".to_string()),
191        Some("CUBESAT".to_string()),
192        ExportCfg::builder().step(Unit::Minute * 2).build(),
193    )?;
194
195    trajectory.to_parquet_with_cfg(
196        "./01_cubesat_hf_prop.parquet",
197        ExportCfg::builder().step(Unit::Minute * 2).build(),
198    )?;
199
200    // 2. Compare the difference in the radial-intrack-crosstrack frame between the high fidelity
201    // and Keplerian propagation. The RIC frame is commonly used to compute the difference in position
202    // and velocity of different spacecraft.
203    // 3. Compute the azimuth, elevation, range, and range-rate data of that spacecraft as seen from Boulder, CO, USA.
204
205    let boulder_station = GroundStation::from_point(
206        "Boulder, CO, USA".to_string(),
207        40.014984,   // latitude in degrees
208        -105.270546, // longitude in degrees
209        1.6550,      // altitude in kilometers
210        almanac.frame_info(IAU_EARTH_FRAME)?,
211    );
212
213    // We iterate over the trajectory, grabbing a state every two minutes.
214    let mut offset_s = vec![];
215    let mut epoch_str = vec![];
216    let mut ric_x_km = vec![];
217    let mut ric_y_km = vec![];
218    let mut ric_z_km = vec![];
219    let mut ric_vx_km_s = vec![];
220    let mut ric_vy_km_s = vec![];
221    let mut ric_vz_km_s = vec![];
222
223    let mut azimuth_deg = vec![];
224    let mut elevation_deg = vec![];
225    let mut range_km = vec![];
226    let mut range_rate_km_s = vec![];
227    for state in trajectory.every(Unit::Minute * 2) {
228        // Try to compute the Keplerian/two body state just in time.
229        // This method occasionally fails to converge on an appropriate true anomaly
230        // from the mean anomaly. If that happens, we just skip this state.
231        // The high fidelity and Keplerian states diverge continuously, and we're curious
232        // about the divergence in this quick analysis.
233        let this_epoch = state.epoch();
234        match orbit.at_epoch(this_epoch) {
235            Ok(tb_then) => {
236                offset_s.push((this_epoch - orbit.epoch).to_seconds());
237                epoch_str.push(format!("{this_epoch}"));
238                // Compute the two body state just in time.
239                let ric = state.orbit.ric_difference(&tb_then)?;
240                ric_x_km.push(ric.radius_km.x);
241                ric_y_km.push(ric.radius_km.y);
242                ric_z_km.push(ric.radius_km.z);
243                ric_vx_km_s.push(ric.velocity_km_s.x);
244                ric_vy_km_s.push(ric.velocity_km_s.y);
245                ric_vz_km_s.push(ric.velocity_km_s.z);
246
247                // Compute the AER data for each state.
248                let aer = almanac.azimuth_elevation_range_sez(
249                    state.orbit,
250                    boulder_station.to_orbit(this_epoch, &almanac)?,
251                    None,
252                    None,
253                )?;
254                azimuth_deg.push(aer.azimuth_deg);
255                elevation_deg.push(aer.elevation_deg);
256                range_km.push(aer.range_km);
257                range_rate_km_s.push(aer.range_rate_km_s);
258            }
259            Err(e) => warn!("{} {e}", state.epoch()),
260        };
261    }
262
263    // Build the data frames.
264    let ric_df = df!(
265        "Offset (s)" => offset_s.clone(),
266        "Epoch" => epoch_str.clone(),
267        "RIC X (km)" => ric_x_km,
268        "RIC Y (km)" => ric_y_km,
269        "RIC Z (km)" => ric_z_km,
270        "RIC VX (km/s)" => ric_vx_km_s,
271        "RIC VY (km/s)" => ric_vy_km_s,
272        "RIC VZ (km/s)" => ric_vz_km_s,
273    )?;
274
275    println!("RIC difference at start\n{}", ric_df.head(Some(10)));
276    println!("RIC difference at end\n{}", ric_df.tail(Some(10)));
277
278    let aer_df = df!(
279        "Offset (s)" => offset_s.clone(),
280        "Epoch" => epoch_str.clone(),
281        "azimuth (deg)" => azimuth_deg,
282        "elevation (deg)" => elevation_deg,
283        "range (km)" => range_km,
284        "range rate (km/s)" => range_rate_km_s,
285    )?;
286
287    // Finally, let's see when the spacecraft is visible, assuming 15 degrees minimum elevation.
288    let mask = aer_df
289        .column("elevation (deg)")?
290        .gt(&Column::Scalar(ScalarColumn::new(
291            "elevation mask (deg)".into(),
292            Scalar::new(DataType::Float64, AnyValue::Float64(15.0)),
293            offset_s.len(),
294        )))?;
295    let cubesat_visible = aer_df.filter(&mask)?;
296
297    println!("{cubesat_visible}");
298
299    Ok(())
300}
Source§

impl<__fields, __start_epoch, __end_epoch, __step, __timestamp> ExportCfgBuilder<(__fields, __start_epoch, __end_epoch, __step, (), __timestamp)>

Source

pub fn metadata( self, metadata: HashMap<String, String>, ) -> ExportCfgBuilder<(__fields, __start_epoch, __end_epoch, __step, (Option<HashMap<String, String>>,), __timestamp)>

Additional metadata to store in the Parquet metadata

Source§

impl<__fields, __start_epoch, __end_epoch, __step, __metadata> ExportCfgBuilder<(__fields, __start_epoch, __end_epoch, __step, __metadata, ())>

Source

pub fn timestamp( self, timestamp: bool, ) -> ExportCfgBuilder<(__fields, __start_epoch, __end_epoch, __step, __metadata, (bool,))>

Set to true to append the timestamp to the filename

Source§

impl<__fields, __start_epoch, __end_epoch, __step, __metadata, __timestamp> ExportCfgBuilder<(__fields, __start_epoch, __end_epoch, __step, __metadata, __timestamp)>
where ExportCfg: for<'__typed_builder_lifetime_for_default> NextFieldDefault<(__fields,), Output = Option<Vec<StateParameter>>> + for<'__typed_builder_lifetime_for_default> NextFieldDefault<(&'__typed_builder_lifetime_for_default Option<Vec<StateParameter>>, __start_epoch), Output = Option<Epoch>> + for<'__typed_builder_lifetime_for_default> NextFieldDefault<(&'__typed_builder_lifetime_for_default Option<Vec<StateParameter>>, &'__typed_builder_lifetime_for_default Option<Epoch>, __end_epoch), Output = Option<Epoch>> + for<'__typed_builder_lifetime_for_default> NextFieldDefault<(&'__typed_builder_lifetime_for_default Option<Vec<StateParameter>>, &'__typed_builder_lifetime_for_default Option<Epoch>, &'__typed_builder_lifetime_for_default Option<Epoch>, __step), Output = Option<Duration>> + for<'__typed_builder_lifetime_for_default> NextFieldDefault<(&'__typed_builder_lifetime_for_default Option<Vec<StateParameter>>, &'__typed_builder_lifetime_for_default Option<Epoch>, &'__typed_builder_lifetime_for_default Option<Epoch>, &'__typed_builder_lifetime_for_default Option<Duration>, __metadata), Output = Option<HashMap<String, String>>> + for<'__typed_builder_lifetime_for_default> NextFieldDefault<(&'__typed_builder_lifetime_for_default Option<Vec<StateParameter>>, &'__typed_builder_lifetime_for_default Option<Epoch>, &'__typed_builder_lifetime_for_default Option<Epoch>, &'__typed_builder_lifetime_for_default Option<Duration>, &'__typed_builder_lifetime_for_default Option<HashMap<String, String>>, __timestamp), Output = bool>,

Source

pub fn build(self) -> ExportCfg

Finalise the builder and create its ExportCfg instance

Examples found in repository?
nyx-core/examples/03_geo_analysis/drift.rs (line 160)
26fn main() -> Result<(), Box<dyn Error>> {
27    pel::init();
28    // Dynamics models require planetary constants and ephemerides to be defined.
29    // Let's start by grabbing those by using ANISE's latest MetaAlmanac.
30    // This will automatically download the DE440s planetary ephemeris,
31    // the daily-updated Earth Orientation Parameters, the high fidelity Moon orientation
32    // parameters (for the Moon Mean Earth and Moon Principal Axes frames), and the PCK11
33    // planetary constants kernels.
34    // For details, refer to https://github.com/nyx-space/anise/blob/master/data/latest.dhall.
35    // Note that we place the Almanac into an Arc so we can clone it cheaply and provide read-only
36    // references to many functions.
37    let almanac = Arc::new(MetaAlmanac::latest().map_err(Box::new)?);
38    // Define the orbit epoch
39    let epoch = Epoch::from_gregorian_utc_hms(2024, 2, 29, 12, 13, 14);
40
41    // Define the orbit.
42    // First we need to fetch the Earth J2000 from information from the Almanac.
43    // This allows the frame to include the gravitational parameters and the shape of the Earth,
44    // defined as a tri-axial ellipoid. Note that this shape can be changed manually or in the Almanac
45    // by loading a different set of planetary constants.
46    let earth_j2000 = almanac.frame_info(EARTH_J2000)?;
47
48    // Placing this GEO bird just above Colorado.
49    // In theory, the eccentricity is zero, but in practice, it's about 1e-5 to 1e-6 at best.
50    let orbit = Orbit::try_keplerian(42164.0, 1e-5, 0., 163.0, 75.0, 0.0, epoch, earth_j2000)?;
51    // Print in in Keplerian form.
52    println!("{orbit:x}");
53
54    let state_bf = almanac.transform_to(orbit, IAU_EARTH_FRAME, None)?;
55    let (orig_lat_deg, orig_long_deg, orig_alt_km) = state_bf.latlongalt()?;
56
57    // Nyx is used for high fidelity propagation, not Keplerian propagation as above.
58    // Nyx only propagates Spacecraft at the moment, which allows it to account for acceleration
59    // models such as solar radiation pressure.
60
61    // Let's build a cubesat sized spacecraft, with an SRP area of 10 cm^2 and a mass of 9.6 kg.
62    let sc = Spacecraft::builder()
63        .orbit(orbit)
64        .mass(Mass::from_dry_mass(9.60))
65        .srp(SRPData {
66            area_m2: 10e-4,
67            coeff_reflectivity: 1.1,
68        })
69        .build();
70    println!("{sc:x}");
71
72    // Set up the spacecraft dynamics.
73
74    // Specify that the orbital dynamics must account for the graviational pull of the Moon and the Sun.
75    // The gravity of the Earth will also be accounted for since the spaceraft in an Earth orbit.
76    let mut orbital_dyn = OrbitalDynamics::point_masses(vec![MOON, SUN]);
77
78    // We want to include the spherical harmonics, so let's download the gravitational data from the Nyx Cloud.
79    // We're using the JGM3 model here, which is the default in GMAT.
80    let mut jgm3_meta = MetaFile {
81        uri: "http://public-data.nyxspace.com/nyx/models/JGM3.cof.gz".to_string(),
82        crc32: Some(0xF446F027), // Specifying the CRC32 avoids redownloading it if it's cached.
83    };
84    // And let's download it if we don't have it yet.
85    jgm3_meta.process(true)?;
86
87    // Build the spherical harmonics.
88    // The harmonics must be computed in the body fixed frame.
89    // We're using the long term prediction of the Earth centered Earth fixed frame, IAU Earth.
90    let harmonics_21x21 = GravityField::new(
91        GravityFieldData::from_cof(
92            &jgm3_meta.uri,
93            21,
94            21,
95            true,
96            almanac.frame_info(IAU_EARTH_FRAME)?,
97        )
98        .unwrap(),
99    );
100
101    // Include the spherical harmonics into the orbital dynamics.
102    orbital_dyn.accel_models.push(harmonics_21x21);
103
104    // We define the solar radiation pressure, using the default solar flux and accounting only
105    // for the eclipsing caused by the Earth and Moon.
106    let srp_dyn = SolarPressure::new(vec![EARTH_J2000, MOON_J2000], &almanac)?;
107
108    // Finalize setting up the dynamics, specifying the force models (orbital_dyn) separately from the
109    // acceleration models (SRP in this case). Use `from_models` to specify multiple accel models.
110    let dynamics = SpacecraftDynamics::from_model(orbital_dyn, srp_dyn);
111
112    println!("{dynamics}");
113
114    // Finally, let's propagate this orbit to the same epoch as above.
115    // The first returned value is the spacecraft state at the final epoch.
116    // The second value is the full trajectory where the step size is variable step used by the propagator.
117    let (future_sc, trajectory) = Propagator::default(dynamics)
118        .with(sc, almanac.clone())
119        .until_epoch_with_traj(epoch + Unit::Century * 0.03)?;
120
121    println!("=== High fidelity propagation ===");
122    println!(
123        "SMA changed by {:.3} km",
124        orbit.sma_km()? - future_sc.orbit.sma_km()?
125    );
126    println!(
127        "ECC changed by {:.6}",
128        orbit.ecc()? - future_sc.orbit.ecc()?
129    );
130    println!(
131        "INC changed by {:.3e} deg",
132        orbit.inc_deg()? - future_sc.orbit.inc_deg()?
133    );
134    println!(
135        "RAAN changed by {:.3} deg",
136        orbit.raan_deg()? - future_sc.orbit.raan_deg()?
137    );
138    println!(
139        "AOP changed by {:.3} deg",
140        orbit.aop_deg()? - future_sc.orbit.aop_deg()?
141    );
142    println!(
143        "TA changed by {:.3} deg",
144        orbit.ta_deg()? - future_sc.orbit.ta_deg()?
145    );
146
147    // We also have access to the full trajectory throughout the propagation.
148    println!("{trajectory}");
149
150    println!("Spacecraft params after 3 years without active control:\n{future_sc:x}");
151
152    // With the trajectory, let's build a few data products.
153
154    // 1. Export the trajectory as a parquet file, which includes the Keplerian orbital elements.
155
156    let analysis_step = Unit::Minute * 5;
157
158    trajectory.to_parquet(
159        "./03_geo_hf_prop.parquet",
160        ExportCfg::builder().step(analysis_step).build(),
161    )?;
162
163    // 2. Compute the latitude, longitude, and altitude throughout the trajectory by rotating the spacecraft position into the Earth body fixed frame.
164
165    // We iterate over the trajectory, grabbing a state every two minutes.
166    let mut offset_s = vec![];
167    let mut epoch_str = vec![];
168    let mut longitude_deg = vec![];
169    let mut latitude_deg = vec![];
170    let mut altitude_km = vec![];
171
172    for state in trajectory.every(analysis_step) {
173        // Convert the GEO bird state into the body fixed frame, and keep track of its latitude, longitude, and altitude.
174        // These define the GEO stationkeeping box.
175
176        let this_epoch = state.epoch();
177
178        offset_s.push((this_epoch - orbit.epoch).to_seconds());
179        epoch_str.push(this_epoch.to_isoformat());
180
181        let state_bf = almanac.transform_to(state.orbit, IAU_EARTH_FRAME, None)?;
182        let (lat_deg, long_deg, alt_km) = state_bf.latlongalt()?;
183        longitude_deg.push(long_deg);
184        latitude_deg.push(lat_deg);
185        altitude_km.push(alt_km);
186    }
187
188    println!(
189        "Longitude changed by {:.3} deg -- Box is 0.1 deg E-W",
190        orig_long_deg - longitude_deg.last().unwrap()
191    );
192
193    println!(
194        "Latitude changed by {:.3} deg -- Box is 0.05 deg N-S",
195        orig_lat_deg - latitude_deg.last().unwrap()
196    );
197
198    println!(
199        "Altitude changed by {:.3} km -- Box is 30 km",
200        orig_alt_km - altitude_km.last().unwrap()
201    );
202
203    // Build the station keeping data frame.
204    let mut sk_df = df!(
205        "Offset (s)" => offset_s.clone(),
206        "Epoch (UTC)" => epoch_str.clone(),
207        "Longitude E-W (deg)" => longitude_deg,
208        "Latitude N-S (deg)" => latitude_deg,
209        "Altitude (km)" => altitude_km,
210
211    )?;
212
213    // Create a file to write the Parquet to
214    let file = File::create("./03_geo_lla.parquet").expect("Could not create file");
215
216    // Create a ParquetWriter and write the DataFrame to the file
217    ParquetWriter::new(file).finish(&mut sk_df)?;
218
219    Ok(())
220}
More examples
Hide additional examples
nyx-core/examples/01_orbit_prop/main.rs (line 192)
30fn main() -> Result<(), Box<dyn Error>> {
31    pel::init();
32    // Dynamics models require planetary constants and ephemerides to be defined.
33    // Let's start by grabbing those by using ANISE's latest MetaAlmanac.
34    // This will automatically download the DE440s planetary ephemeris,
35    // the daily-updated Earth Orientation Parameters, the high fidelity Moon orientation
36    // parameters (for the Moon Mean Earth and Moon Principal Axes frames), and the PCK11
37    // planetary constants kernels.
38    // For details, refer to https://github.com/nyx-space/anise/blob/master/data/latest.dhall.
39    // Note that we place the Almanac into an Arc so we can clone it cheaply and provide read-only
40    // references to many functions.
41    let almanac = Arc::new(MetaAlmanac::latest().map_err(Box::new)?);
42    // Define the orbit epoch
43    let epoch = Epoch::from_gregorian_utc_hms(2024, 2, 29, 12, 13, 14);
44
45    // Define the orbit.
46    // First we need to fetch the Earth J2000 from information from the Almanac.
47    // This allows the frame to include the gravitational parameters and the shape of the Earth,
48    // defined as a tri-axial ellipoid. Note that this shape can be changed manually or in the Almanac
49    // by loading a different set of planetary constants.
50    let earth_j2000 = almanac.frame_info(EARTH_J2000)?;
51
52    let orbit =
53        Orbit::try_keplerian_altitude(300.0, 0.015, 68.5, 65.2, 75.0, 0.0, epoch, earth_j2000)?;
54    // Print in in Keplerian form.
55    println!("{orbit:x}");
56
57    // There are two ways to propagate an orbit. We can make a quick approximation assuming only two-body
58    // motion. This is a useful first order approximation but it isn't used in real-world applications.
59
60    // This approach is a feature of ANISE.
61    let future_orbit_tb = orbit.at_epoch(epoch + Unit::Day * 3)?;
62    println!("{future_orbit_tb:x}");
63
64    // Two body propagation relies solely on Kepler's laws, so only the true anomaly will change.
65    println!(
66        "SMA changed by {:.3e} km",
67        orbit.sma_km()? - future_orbit_tb.sma_km()?
68    );
69    println!(
70        "ECC changed by {:.3e}",
71        orbit.ecc()? - future_orbit_tb.ecc()?
72    );
73    println!(
74        "INC changed by {:.3e} deg",
75        orbit.inc_deg()? - future_orbit_tb.inc_deg()?
76    );
77    println!(
78        "RAAN changed by {:.3e} deg",
79        orbit.raan_deg()? - future_orbit_tb.raan_deg()?
80    );
81    println!(
82        "AOP changed by {:.3e} deg",
83        orbit.aop_deg()? - future_orbit_tb.aop_deg()?
84    );
85    println!(
86        "TA changed by {:.3} deg",
87        orbit.ta_deg()? - future_orbit_tb.ta_deg()?
88    );
89
90    // Nyx is used for high fidelity propagation, not Keplerian propagation as above.
91    // Nyx only propagates Spacecraft at the moment, which allows it to account for acceleration
92    // models such as solar radiation pressure.
93
94    // Let's build a cubesat sized spacecraft, with an SRP area of 10 cm^2 and a mass of 9.6 kg.
95    let sc = Spacecraft::builder()
96        .orbit(orbit)
97        .mass(Mass::from_dry_mass(9.60))
98        .srp(SRPData {
99            area_m2: 10e-4,
100            coeff_reflectivity: 1.1,
101        })
102        .build();
103    println!("{sc:x}");
104
105    // Set up the spacecraft dynamics.
106
107    // Specify that the orbital dynamics must account for the graviational pull of the Moon and the Sun.
108    // The gravity of the Earth will also be accounted for since the spaceraft in an Earth orbit.
109    let mut orbital_dyn = OrbitalDynamics::point_masses(vec![MOON, SUN]);
110
111    // We want to include the spherical harmonics, so let's download the gravitational data from the Nyx Cloud.
112    // We're using the JGM3 model here, which is the default in GMAT.
113    let mut jgm3_meta = MetaFile {
114        uri: "http://public-data.nyxspace.com/nyx/models/JGM3.cof.gz".to_string(),
115        crc32: Some(0xF446F027), // Specifying the CRC32 avoids redownloading it if it's cached.
116    };
117    // And let's download it if we don't have it yet.
118    jgm3_meta.process(true)?;
119
120    // Build the spherical harmonics.
121    // The harmonics must be computed in the body fixed frame.
122    // We're using the long term prediction of the Earth centered Earth fixed frame, IAU Earth.
123    let harmonics_21x21 = GravityField::new(
124        GravityFieldData::from_cof(
125            &jgm3_meta.uri,
126            21,
127            21,
128            true,
129            almanac.frame_info(IAU_EARTH_FRAME)?,
130        )
131        .unwrap(),
132    );
133
134    // Include the spherical harmonics into the orbital dynamics.
135    orbital_dyn.accel_models.push(harmonics_21x21);
136
137    // We define the solar radiation pressure, using the default solar flux and accounting only
138    // for the eclipsing caused by the Earth.
139    let srp_dyn = SolarPressure::default_flux(EARTH_J2000, &almanac)?;
140
141    // Finalize setting up the dynamics, specifying the force models (orbital_dyn) separately from the
142    // acceleration models (SRP in this case). Use `from_models` to specify multiple accel models.
143    let dynamics = SpacecraftDynamics::from_model(orbital_dyn, srp_dyn);
144
145    println!("{dynamics}");
146
147    // Finally, let's propagate this orbit to the same epoch as above.
148    // The first returned value is the spacecraft state at the final epoch.
149    // The second value is the full trajectory where the step size is variable step used by the propagator.
150    let (future_sc, trajectory) = Propagator::default(dynamics)
151        .with(sc, almanac.clone())
152        .until_epoch_with_traj(future_orbit_tb.epoch)?;
153
154    println!("=== High fidelity propagation ===");
155    println!(
156        "SMA changed by {:.3} km",
157        orbit.sma_km()? - future_sc.orbit.sma_km()?
158    );
159    println!(
160        "ECC changed by {:.6}",
161        orbit.ecc()? - future_sc.orbit.ecc()?
162    );
163    println!(
164        "INC changed by {:.3e} deg",
165        orbit.inc_deg()? - future_sc.orbit.inc_deg()?
166    );
167    println!(
168        "RAAN changed by {:.3} deg",
169        orbit.raan_deg()? - future_sc.orbit.raan_deg()?
170    );
171    println!(
172        "AOP changed by {:.3} deg",
173        orbit.aop_deg()? - future_sc.orbit.aop_deg()?
174    );
175    println!(
176        "TA changed by {:.3} deg",
177        orbit.ta_deg()? - future_sc.orbit.ta_deg()?
178    );
179
180    // We also have access to the full trajectory throughout the propagation.
181    println!("{trajectory}");
182
183    // With the trajectory, let's build a few data products.
184
185    // 1. Export the trajectory as a CCSDS OEM version 2.0 file and as a parquet file, which includes the Keplerian orbital elements.
186
187    trajectory.to_oem_file(
188        "./01_cubesat_hf_prop.oem",
189        "CUBESAT-ID".to_string(),
190        Some("Nyx Space".to_string()),
191        Some("CUBESAT".to_string()),
192        ExportCfg::builder().step(Unit::Minute * 2).build(),
193    )?;
194
195    trajectory.to_parquet_with_cfg(
196        "./01_cubesat_hf_prop.parquet",
197        ExportCfg::builder().step(Unit::Minute * 2).build(),
198    )?;
199
200    // 2. Compare the difference in the radial-intrack-crosstrack frame between the high fidelity
201    // and Keplerian propagation. The RIC frame is commonly used to compute the difference in position
202    // and velocity of different spacecraft.
203    // 3. Compute the azimuth, elevation, range, and range-rate data of that spacecraft as seen from Boulder, CO, USA.
204
205    let boulder_station = GroundStation::from_point(
206        "Boulder, CO, USA".to_string(),
207        40.014984,   // latitude in degrees
208        -105.270546, // longitude in degrees
209        1.6550,      // altitude in kilometers
210        almanac.frame_info(IAU_EARTH_FRAME)?,
211    );
212
213    // We iterate over the trajectory, grabbing a state every two minutes.
214    let mut offset_s = vec![];
215    let mut epoch_str = vec![];
216    let mut ric_x_km = vec![];
217    let mut ric_y_km = vec![];
218    let mut ric_z_km = vec![];
219    let mut ric_vx_km_s = vec![];
220    let mut ric_vy_km_s = vec![];
221    let mut ric_vz_km_s = vec![];
222
223    let mut azimuth_deg = vec![];
224    let mut elevation_deg = vec![];
225    let mut range_km = vec![];
226    let mut range_rate_km_s = vec![];
227    for state in trajectory.every(Unit::Minute * 2) {
228        // Try to compute the Keplerian/two body state just in time.
229        // This method occasionally fails to converge on an appropriate true anomaly
230        // from the mean anomaly. If that happens, we just skip this state.
231        // The high fidelity and Keplerian states diverge continuously, and we're curious
232        // about the divergence in this quick analysis.
233        let this_epoch = state.epoch();
234        match orbit.at_epoch(this_epoch) {
235            Ok(tb_then) => {
236                offset_s.push((this_epoch - orbit.epoch).to_seconds());
237                epoch_str.push(format!("{this_epoch}"));
238                // Compute the two body state just in time.
239                let ric = state.orbit.ric_difference(&tb_then)?;
240                ric_x_km.push(ric.radius_km.x);
241                ric_y_km.push(ric.radius_km.y);
242                ric_z_km.push(ric.radius_km.z);
243                ric_vx_km_s.push(ric.velocity_km_s.x);
244                ric_vy_km_s.push(ric.velocity_km_s.y);
245                ric_vz_km_s.push(ric.velocity_km_s.z);
246
247                // Compute the AER data for each state.
248                let aer = almanac.azimuth_elevation_range_sez(
249                    state.orbit,
250                    boulder_station.to_orbit(this_epoch, &almanac)?,
251                    None,
252                    None,
253                )?;
254                azimuth_deg.push(aer.azimuth_deg);
255                elevation_deg.push(aer.elevation_deg);
256                range_km.push(aer.range_km);
257                range_rate_km_s.push(aer.range_rate_km_s);
258            }
259            Err(e) => warn!("{} {e}", state.epoch()),
260        };
261    }
262
263    // Build the data frames.
264    let ric_df = df!(
265        "Offset (s)" => offset_s.clone(),
266        "Epoch" => epoch_str.clone(),
267        "RIC X (km)" => ric_x_km,
268        "RIC Y (km)" => ric_y_km,
269        "RIC Z (km)" => ric_z_km,
270        "RIC VX (km/s)" => ric_vx_km_s,
271        "RIC VY (km/s)" => ric_vy_km_s,
272        "RIC VZ (km/s)" => ric_vz_km_s,
273    )?;
274
275    println!("RIC difference at start\n{}", ric_df.head(Some(10)));
276    println!("RIC difference at end\n{}", ric_df.tail(Some(10)));
277
278    let aer_df = df!(
279        "Offset (s)" => offset_s.clone(),
280        "Epoch" => epoch_str.clone(),
281        "azimuth (deg)" => azimuth_deg,
282        "elevation (deg)" => elevation_deg,
283        "range (km)" => range_km,
284        "range rate (km/s)" => range_rate_km_s,
285    )?;
286
287    // Finally, let's see when the spacecraft is visible, assuming 15 degrees minimum elevation.
288    let mask = aer_df
289        .column("elevation (deg)")?
290        .gt(&Column::Scalar(ScalarColumn::new(
291            "elevation mask (deg)".into(),
292            Scalar::new(DataType::Float64, AnyValue::Float64(15.0)),
293            offset_s.len(),
294        )))?;
295    let cubesat_visible = aer_df.filter(&mask)?;
296
297    println!("{cubesat_visible}");
298
299    Ok(())
300}

Trait Implementations§

Source§

impl<TypedBuilderFields> Clone for ExportCfgBuilder<TypedBuilderFields>
where TypedBuilderFields: Clone,

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<TypedBuilderFields> Freeze for ExportCfgBuilder<TypedBuilderFields>
where TypedBuilderFields: Freeze,

§

impl<TypedBuilderFields> RefUnwindSafe for ExportCfgBuilder<TypedBuilderFields>
where TypedBuilderFields: RefUnwindSafe,

§

impl<TypedBuilderFields> Send for ExportCfgBuilder<TypedBuilderFields>
where TypedBuilderFields: Send,

§

impl<TypedBuilderFields> Sync for ExportCfgBuilder<TypedBuilderFields>
where TypedBuilderFields: Sync,

§

impl<TypedBuilderFields> Unpin for ExportCfgBuilder<TypedBuilderFields>
where TypedBuilderFields: Unpin,

§

impl<TypedBuilderFields> UnsafeUnpin for ExportCfgBuilder<TypedBuilderFields>
where TypedBuilderFields: UnsafeUnpin,

§

impl<TypedBuilderFields> UnwindSafe for ExportCfgBuilder<TypedBuilderFields>
where TypedBuilderFields: UnwindSafe,

Blanket Implementations§

§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Ungil for T
where T: Send,

§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more