diff --git a/docs/anise/reference/api/python/astro.md b/docs/anise/reference/api/python/astro.md
index 898d9f1..8932f5b 100644
--- a/docs/anise/reference/api/python/astro.md
+++ b/docs/anise/reference/api/python/astro.md
@@ -1,14 +1,24 @@
-# Module `anise.astro` {#anise.astro}
+---
+description: |
+ API documentation for modules: anise.astro.
+
+lang: en
+
+classoption: oneside
+geometry: margin=1in
+papersize: a4
+
+linkcolor: blue
+links-as-notes: true
+...
-
-## Sub-modules
-* [anise.astro.constants](#anise.astro.constants)
+# Module `anise.astro` {#anise.astro}
+
-
## Classes
-
+
### Class `AzElRange` {#anise.astro.AzElRange}
> class AzElRange(
@@ -17,7 +27,8 @@
> elevation_deg,
> range_km,
> range_rate_km_s,
-> obstructed_by=None
+> obstructed_by=None,
+> mask_deg=None
> )
A structure that stores the result of Azimuth, Elevation, Range, Range rate calculation.
@@ -28,50 +39,69 @@ A structure that stores the result of Azimuth, Elevation, Range, Range rate calc
:type range_km: float
:type range_rate_km_s: float
:type obstructed_by: Frame, optional
+:type mask_deg: float, optional
:rtype: AzElRange
-
+
#### Instance variables
-
+
##### Variable `azimuth_deg` {#anise.astro.AzElRange.azimuth_deg}
:rtype: float
-
+
##### Variable `elevation_deg` {#anise.astro.AzElRange.elevation_deg}
:rtype: float
-
+
##### Variable `epoch` {#anise.astro.AzElRange.epoch}
:rtype: Epoch
-
+
##### Variable `light_time` {#anise.astro.AzElRange.light_time}
:rtype: Duration
-
+
+##### Variable `mask_deg` {#anise.astro.AzElRange.mask_deg}
+
+:rtype: float
+
+
##### Variable `obstructed_by` {#anise.astro.AzElRange.obstructed_by}
:rtype: Frame
-
+
##### Variable `range_km` {#anise.astro.AzElRange.range_km}
:rtype: float
-
+
##### Variable `range_rate_km_s` {#anise.astro.AzElRange.range_rate_km_s}
:rtype: float
-
+
#### Methods
-
+
+##### Method `elevation_above_mask_deg` {#anise.astro.AzElRange.elevation_above_mask_deg}
+
+> def elevation_above_mask_deg(
+> self,
+> /
+> )
+
+Returns the elevation above the terrain mask for this azimuth, in degrees.
+If the terrain mask was zero at this azimuth, then the elevation above mask is equal to the elevation_deg field.
+
+:rtype: float
+
+
##### Method `is_obstructed` {#anise.astro.AzElRange.is_obstructed}
> def is_obstructed(
@@ -83,7 +113,7 @@ Returns whether there is an obstruction.
:rtype: bool
-
+
##### Method `is_valid` {#anise.astro.AzElRange.is_valid}
> def is_valid(
@@ -95,7 +125,324 @@ Returns false if the range is less than one millimeter, or any of the angles are
:rtype: bool
-
+
+### Class `Covariance` {#anise.astro.Covariance}
+
+> class Covariance(
+> covar,
+> local_frame
+> )
+
+
+#### Instance variables
+
+
+##### Variable `matrix` {#anise.astro.Covariance.matrix}
+
+Returns the 6x6 DCM to rotate a state. If the time derivative of this DCM is defined, this 6x6 accounts for the transport theorem.
+Warning: you MUST manually install numpy to call this function.
+:rtype: numpy.ndarray
+
+
+### Class `DataType` {#anise.astro.DataType}
+
+> class DataType
+
+
+#### Class variables
+
+
+##### Variable `Type10SpaceCommandTLE` {#anise.astro.DataType.Type10SpaceCommandTLE}
+
+
+##### Variable `Type12HermiteEqualStep` {#anise.astro.DataType.Type12HermiteEqualStep}
+
+
+##### Variable `Type13HermiteUnequalStep` {#anise.astro.DataType.Type13HermiteUnequalStep}
+
+
+##### Variable `Type14ChebyshevUnequalStep` {#anise.astro.DataType.Type14ChebyshevUnequalStep}
+
+
+##### Variable `Type15PrecessingConics` {#anise.astro.DataType.Type15PrecessingConics}
+
+
+##### Variable `Type17Equinoctial` {#anise.astro.DataType.Type17Equinoctial}
+
+
+##### Variable `Type18ESOCHermiteLagrange` {#anise.astro.DataType.Type18ESOCHermiteLagrange}
+
+
+##### Variable `Type19ESOCPiecewise` {#anise.astro.DataType.Type19ESOCPiecewise}
+
+
+##### Variable `Type1ModifiedDifferenceArray` {#anise.astro.DataType.Type1ModifiedDifferenceArray}
+
+
+##### Variable `Type20ChebyshevDerivative` {#anise.astro.DataType.Type20ChebyshevDerivative}
+
+
+##### Variable `Type21ExtendedModifiedDifferenceArray` {#anise.astro.DataType.Type21ExtendedModifiedDifferenceArray}
+
+
+##### Variable `Type2ChebyshevTriplet` {#anise.astro.DataType.Type2ChebyshevTriplet}
+
+
+##### Variable `Type3ChebyshevSextuplet` {#anise.astro.DataType.Type3ChebyshevSextuplet}
+
+
+##### Variable `Type5DiscreteStates` {#anise.astro.DataType.Type5DiscreteStates}
+
+
+##### Variable `Type8LagrangeEqualStep` {#anise.astro.DataType.Type8LagrangeEqualStep}
+
+
+##### Variable `Type9LagrangeUnequalStep` {#anise.astro.DataType.Type9LagrangeUnequalStep}
+
+
+### Class `DragData` {#anise.astro.DragData}
+
+> class DragData(
+> area_m2,
+> coeff_drag=None
+> )
+
+
+#### Instance variables
+
+
+##### Variable `area_m2` {#anise.astro.DragData.area_m2}
+
+Atmospheric drag area in m^2 -- default 0.0
+:rtype: float
+
+
+##### Variable `coeff_drag` {#anise.astro.DragData.coeff_drag}
+
+Drag coefficient (C_d) -- default 2.2
+:rtype: float
+
+
+#### Methods
+
+
+##### Method `from_asn1` {#anise.astro.DragData.from_asn1}
+
+> def from_asn1(
+> data
+> )
+
+Decodes an ASN.1 DER encoded byte array into a DragData object.
+
+:type data: bytes
+:rtype: DragData
+
+
+##### Method `to_asn1` {#anise.astro.DragData.to_asn1}
+
+> def to_asn1(
+> self,
+> /
+> )
+
+Encodes this DragData object into an ASN.1 DER encoded byte array.
+
+:rtype: bytes
+
+
+### Class `DynamicFrame` {#anise.astro.DynamicFrame}
+
+> class DynamicFrame
+
+Dynamic frames in ANISE are encoded as a packed integer within the frame's orientation ID.
+
+### Encoding format
+
+The identifier is a 32-bit signed integer packed as four bytes:
+```text
+ 0xA0 FF AA BB
+```
+Where:
+
+ - 0xA0: ANISE dynamic frame prefix.
+ - FF: Frame family identifier (e.g., Earth Mean of Date, Body True of Date).
+ - AA: Primary payload (e.g., precession model for Earth frames, or the high byte of a source ID).
+ - BB: Secondary payload (e.g., nutation model for Earth frames, or the low byte of a source ID).
+
+### Frame families
+
+```text
+ 0xA0 E0 AA 00 Earth Mean Equator, Mean Equinox of Date (MOD)
+ 0xA0 E1 AA BB Earth True Equator, True Equinox of Date (TOD)
+ 0xA0 E2 AA BB Earth True Equator, Mean Equinox of Date (TEME)
+
+ 0xA0 B0 SS SS Body Mean of Date
+ 0xA0 B1 SS SS Body True of Date
+```
+
+The `E*` families are Earth-specific models. The `B*` families are generic celestial-body pole models.
+
+### Earth payload
+
+For Earth frames, AA encodes the precession / bias-precession model:
+
+```text
+ 0x00 IAU 1976 / FK5 precession
+ 0x01 IAU 2000 precession-bias model
+ 0x03 IAU 2006 precession-bias model
+```
+
+*(Note: 0x02 is intentionally reserved and unused).*
+
+For Earth TOD and TEME frames, BB encodes the nutation model:
+
+```text
+ 0x00 IAU 1980 nutation
+ 0x01 IAU 2000A nutation
+ 0x02 IAU 2000B nutation
+ 0x03 IAU 2006 / 2000A-compatible nutation
+```
+
+For Earth MOD frames, BB is reserved and must strictly be 0x00.
+
+Earth MOD uses the selected precession model only. Earth TOD composes the selected precession and nutation models.
+Earth TEME first builds the corresponding true-equator/true-equinox frame, then rotates about the true Z-axis by the equation of the equinoxes to replace the true equinox with the mean equinox.
+
+For Earth TEME, the equation of the equinoxes model is strictly derived from the selected nutation model:
+
+```text
+ IAU1980 -> EQEQ94
+ IAU2000A -> EE00A
+ IAU2000B -> EE00B
+ IAU2006A -> EE06A
+```
+
+This aligns with the SOFA/SOFARS sidereal-time identity:
+`apparent sidereal time = mean sidereal time + equation of the equinoxes`.
+
+### Body payload
+
+For generic body frames, AA BB is interpreted as a single unsigned 16-bit source orientation ID:
+
+```text
+ source_id = u16::from_be_bytes([AA, BB])
+```
+
+While the public enum stores this as an i32 for seamless integration with ANISE and NAIF ID routing, the compact bitmask fundamentally restricts the payload.
+The source ID MUST be strictly positive and fall within the `0..=65535` range.
+
+This perfectly accommodates standard celestial-body orientation IDs (e.g., 301 for the Moon, or 31001 for a lunar ME-style frame). **It cannot represent negative spacecraft IDs or deeply nested user-defined SPICE frames.**
+
+**Warning:** Out-of-range body source IDs will fail silently via bitwise truncation. Callers must treat the u16 bound as a strict mathematical contract.
+
+Body TOD and MOD frames use the source orientation model solely to establish the body's pole direction. The source prime meridian (twist) angle is explicitly ignored.
+
+- **Body True of Date** uses the full source pole model, inclusive of periodic trigonometric terms.
+- **Body Mean of Date** uses the mean source pole model, zeroing out periodic trigonometric terms in the pole right ascension and declination.
+
+For body TOD/MOD, the dynamic frame axes evaluate as follows via the same Euler rotations code at the PCK-defined IAU frames:
+
+```text
+ Z = source pole direction
+ X = normalize(parent_Z × Z)
+ Y = Z × X
+```
+
+If `parent_Z × Z` evaluates as singular (i.e., the pole aligns with the inertial Z-axis), the fallback perfectly mirrors the Ansys STK specification:
+
+```text
+ Y = normalize(Z × parent_X)
+ X = Y × Z
+```
+
+### Interaction with [Frame](#anise.astro.Frame "anise.astro.Frame") fields
+
+- `Frame::frozen_epoch`: If set, evaluates the dynamic models (precession, nutation, pole right ascension/declination) at the specified epoch rather than the integration time, freezing the frame inertially.
+- `Frame::force_inertial`: If true, the time derivative of the resulting Direction Cosine Matrix (DCM) is explicitly zeroed out. The built-in Earth MOD/TOD constants are defined as inertial in the ANISE constants.
+
+
+#### Descendants
+
+* [anise.astro.DynamicFrame.BodyMeanOfDate](#anise.astro.DynamicFrame.BodyMeanOfDate)
+* [anise.astro.DynamicFrame.BodyTrueOfDate](#anise.astro.DynamicFrame.BodyTrueOfDate)
+* [anise.astro.DynamicFrame.EarthMeanOfDate](#anise.astro.DynamicFrame.EarthMeanOfDate)
+* [anise.astro.DynamicFrame.EarthTrueEquatorMeanEquinox](#anise.astro.DynamicFrame.EarthTrueEquatorMeanEquinox)
+* [anise.astro.DynamicFrame.EarthTrueOfDate](#anise.astro.DynamicFrame.EarthTrueOfDate)
+
+
+#### Class variables
+
+
+##### Variable `BodyMeanOfDate` {#anise.astro.DynamicFrame.BodyMeanOfDate}
+
+
+##### Variable `BodyTrueOfDate` {#anise.astro.DynamicFrame.BodyTrueOfDate}
+
+
+##### Variable `EarthMeanOfDate` {#anise.astro.DynamicFrame.EarthMeanOfDate}
+
+
+##### Variable `EarthTrueEquatorMeanEquinox` {#anise.astro.DynamicFrame.EarthTrueEquatorMeanEquinox}
+
+
+##### Variable `EarthTrueOfDate` {#anise.astro.DynamicFrame.EarthTrueOfDate}
+
+
+#### Methods
+
+
+##### Method `from_frame_id` {#anise.astro.DynamicFrame.from_frame_id}
+
+> def from_frame_id(
+> frame_id
+> )
+
+
+##### Method `to_frame_id` {#anise.astro.DynamicFrame.to_frame_id}
+
+> def to_frame_id(
+> self,
+> /
+> )
+
+
+### Class `EarthNutationModel` {#anise.astro.EarthNutationModel}
+
+> class EarthNutationModel
+
+
+#### Class variables
+
+
+##### Variable `IAU1980` {#anise.astro.EarthNutationModel.IAU1980}
+
+
+##### Variable `IAU2000A` {#anise.astro.EarthNutationModel.IAU2000A}
+
+
+##### Variable `IAU2000B` {#anise.astro.EarthNutationModel.IAU2000B}
+
+
+##### Variable `IAU2006A` {#anise.astro.EarthNutationModel.IAU2006A}
+
+
+### Class `EarthPrecessionModel` {#anise.astro.EarthPrecessionModel}
+
+> class EarthPrecessionModel
+
+
+#### Class variables
+
+
+##### Variable `IAU1976` {#anise.astro.EarthPrecessionModel.IAU1976}
+
+
+##### Variable `IAU2000` {#anise.astro.EarthPrecessionModel.IAU2000}
+
+
+##### Variable `IAU2006` {#anise.astro.EarthPrecessionModel.IAU2006}
+
+
### Class `Ellipsoid` {#anise.astro.Ellipsoid}
> class Ellipsoid(
@@ -120,28 +467,28 @@ Example: Radii of the Earth.
:type semi_minor_equatorial_radius_km: float, optional
:rtype: Ellipsoid
-
+
#### Instance variables
-
+
##### Variable `polar_radius_km` {#anise.astro.Ellipsoid.polar_radius_km}
:rtype: float
-
+
##### Variable `semi_major_equatorial_radius_km` {#anise.astro.Ellipsoid.semi_major_equatorial_radius_km}
:rtype: float
-
+
##### Variable `semi_minor_equatorial_radius_km` {#anise.astro.Ellipsoid.semi_minor_equatorial_radius_km}
:rtype: float
-
+
#### Methods
-
+
##### Method `flattening` {#anise.astro.Ellipsoid.flattening}
> def flattening(
@@ -153,7 +500,7 @@ Returns the flattening ratio, computed from the mean equatorial radius and the p
:rtype: float
-
+
##### Method `is_sphere` {#anise.astro.Ellipsoid.is_sphere}
> def is_sphere(
@@ -165,7 +512,7 @@ Returns true if the polar radius is equal to the semi minor radius.
:rtype: bool
-
+
##### Method `is_spheroid` {#anise.astro.Ellipsoid.is_spheroid}
> def is_spheroid(
@@ -177,7 +524,7 @@ Returns true if the semi major and minor radii are equal
:rtype: bool
-
+
##### Method `mean_equatorial_radius_km` {#anise.astro.Ellipsoid.mean_equatorial_radius_km}
> def mean_equatorial_radius_km(
@@ -189,74 +536,571 @@ Returns the mean equatorial radius in kilometers
:rtype: float
-
-### Class `Frame` {#anise.astro.Frame}
-> class Frame(
-> ephemeris_id,
-> orientation_id,
-> mu_km3_s2=None,
-> shape=None
+### Class `Ephemeris` {#anise.astro.Ephemeris}
+
+> class Ephemeris(
+> orbit_list,
+> object_id
> )
-A Frame uniquely defined by its ephemeris center and orientation. Refer to FrameDetail for frames combined with parameters.
+Initializes a new Ephemeris from the list of Orbit instances and a given object ID.
+
+In Python if you need to build an ephemeris with covariance, initialize with an empty list of
+orbit instances and then insert each EphemerisRecord with covariance.
+
+:type orbit_list: list
+:type object_id: str
-:type ephemeris_id: int
-:type orientation_id: int
-:type mu_km3_s2: float, optional
-:type shape: Ellipsoid, optional
-:rtype: Frame
-
#### Instance variables
-
-##### Variable `ephemeris_id` {#anise.astro.Frame.ephemeris_id}
+
+##### Variable `degree` {#anise.astro.Ephemeris.degree}
:rtype: int
-
-##### Variable `orientation_id` {#anise.astro.Frame.orientation_id}
-:rtype: int
+##### Variable `interpolation` {#anise.astro.Ephemeris.interpolation}
-
-##### Variable `shape` {#anise.astro.Frame.shape}
+:rtype: str
-:rtype: Ellipsoid
-
#### Methods
-
-##### Method `ephem_origin_id_match` {#anise.astro.Frame.ephem_origin_id_match}
-> def ephem_origin_id_match(
+##### Method `at` {#anise.astro.Ephemeris.at}
+
+> def at(
> self,
> /,
-> other_id
+> epoch,
+> almanac
> )
-Returns true if the ephemeris origin is equal to the provided ID
+Interpolates the ephemeris state and covariance at the provided epoch.
-:type other_id: int
-:rtype: bool
+##### Orbit Interpolation
+The orbital state is interpolated using high-fidelity numeric methods consistent
+with SPICE standards:
-
-##### Method `ephem_origin_match` {#anise.astro.Frame.ephem_origin_match}
+* **Type 9 (Lagrange):** Uses an Nth-order Lagrange polynomial interpolation on
+ unequal time steps. It interpolates each of the 6 state components (position
+ and velocity) independently.
-> def ephem_origin_match(
+* **Type 13 (Hermite):** Uses an Nth-order Hermite interpolation. This method
+ explicitly uses the velocity data (derivatives) to constrain the interpolation
+ of the position, ensuring that the resulting position curve is smooth and
+ dynamically consistent with the velocity.
+
+##### Covariance Interpolation (Log-Euclidean)
+If covariance data is available, this method performs **Log-Euclidean Riemannian
+Interpolation**. Unlike standard linear element-wise interpolation, this approach
+respects the geometric manifold of Symmetric Positive Definite (SPD) matrices.
+
+This guarantees that:
+
+1. **Positive Definiteness:** The interpolated covariance matrix is always mathematically
+ valid (all eigenvalues are strictly positive), preventing numerical crashes in downstream filters.
+2. **Volume Preservation:** It prevents the artificial "swelling" (determinant increase)
+ of uncertainty that occurs when linearly interpolating between two valid matrices.
+ The interpolation follows the "geodesic" (shortest path) on the curved surface of
+ covariance matrices.
+
+:type epoch: Epoch
+:type almanac: Almanac
+:rtype: EphemerisRecord
+
+
+##### Method `covar_at` {#anise.astro.Ephemeris.covar_at}
+
+> def covar_at(
> self,
> /,
-> other
+> epoch,
+> local_frame,
+> almanac
> )
-Returns true if the ephemeris origin is equal to the provided frame
+Interpolate the ephemeris covariance at the provided epoch.
+
+This method implements a "Rotate-Then-Interpolate" strategy to avoid physical
+artifacts when interpolating rotating covariances.
+
+
+1. Finds the nearest covariance before and after the requested epoch.
+2. Rotates BOTH endpoints into the requested local\_frame.
+3. Interpolates between the two stable matrices using Log-Euclidean Riemannian interpolation.
+
+:type epoch: Epoch
+:type local_frame: LocalFrame
+:type almanac: Almanac
+:rtype: Covariance
+
+
+##### Method `domain` {#anise.astro.Ephemeris.domain}
+
+> def domain(
+> self,
+> /
+> )
+
+Returns the time domain of this ephemeris.
+
+:rtype: tuple
+
+
+##### Method `end_epoch` {#anise.astro.Ephemeris.end_epoch}
+
+> def end_epoch(
+> self,
+> /
+> )
+
+:rtype: Epoch
+
+
+##### Method `from_ccsds_oem_file` {#anise.astro.Ephemeris.from_ccsds_oem_file}
+
+> def from_ccsds_oem_file(
+> path
+> )
+
+Initializes a new Ephemeris from a file path to CCSDS OEM file.
+
+:type path: str
+:rtype: Ephemeris
+
+
+##### Method `from_stk_e_file` {#anise.astro.Ephemeris.from_stk_e_file}
+
+> def from_stk_e_file(
+> path
+> )
+
+Initializes a new Ephemeris from a file path to Ansys STK .e file.
+
+:type path: str
+:rtype: Ephemeris
+
+
+##### Method `get_object_id` {#anise.astro.Ephemeris.get_object_id}
+
+> def get_object_id(
+> self,
+> /
+> )
+
+:rtype: str
+
+
+##### Method `includes_covariance` {#anise.astro.Ephemeris.includes_covariance}
+
+> def includes_covariance(
+> self,
+> /
+> )
+
+Returns true if all of the data in this ephemeris includes covariance.
+
+This is a helper function which isn't used in other functions.
+
+:rtype: bool
+
+
+##### Method `insert` {#anise.astro.Ephemeris.insert}
+
+> def insert(
+> self,
+> /,
+> record
+> )
+
+Inserts a new ephemeris entry to this ephemeris (it is automatically sorted chronologically).
+:type record: EphemerisRecord
+:rtype: None
+
+
+##### Method `insert_orbit` {#anise.astro.Ephemeris.insert_orbit}
+
+> def insert_orbit(
+> self,
+> /,
+> orbit
+> )
+
+Inserts a new orbit (without covariance) to this ephemeris (it is automatically sorted chronologically).
+:type orbit: Orbit
+:rtype: None
+
+
+##### Method `len` {#anise.astro.Ephemeris.len}
+
+> def len(
+> self,
+> /
+> )
+
+Returns the number of states
+
+:rtype: int
+
+
+##### Method `nearest_after` {#anise.astro.Ephemeris.nearest_after}
+
+> def nearest_after(
+> self,
+> /,
+> epoch,
+> almanac
+> )
+
+Returns the nearest entry after the provided time
+
+:type epoch: Epoch
+:type almanac: Almanac
+:rtype: EphemerisRecord
+
+
+##### Method `nearest_before` {#anise.astro.Ephemeris.nearest_before}
+
+> def nearest_before(
+> self,
+> /,
+> epoch,
+> almanac
+> )
+
+Returns the nearest entry before the provided time
+
+:type epoch: Epoch
+:type almanac: Almanac
+:rtype: EphemerisRecord
+
+
+##### Method `nearest_covar_after` {#anise.astro.Ephemeris.nearest_covar_after}
+
+> def nearest_covar_after(
+> self,
+> /,
+> epoch,
+> almanac
+> )
+
+Returns the nearest covariance after the provided epoch as a tuple (Epoch, Covariance)
+
+:type epoch: Epoch
+:type almanac: Almanac
+:rtype: tuple
+
+
+##### Method `nearest_covar_before` {#anise.astro.Ephemeris.nearest_covar_before}
+
+> def nearest_covar_before(
+> self,
+> /,
+> epoch,
+> almanac
+> )
+
+Returns the nearest covariance before the provided epoch as a tuple (Epoch, Covariance)
+
+:type epoch: Epoch
+:type almanac: Almanac
+:rtype: tuple
+
+
+##### Method `nearest_orbit_after` {#anise.astro.Ephemeris.nearest_orbit_after}
+
+> def nearest_orbit_after(
+> self,
+> /,
+> epoch,
+> almanac
+> )
+
+Returns the nearest orbit after the provided time
+
+:type epoch: Epoch
+:type almanac: Almanac
+:rtype: Orbit
+
+
+##### Method `nearest_orbit_before` {#anise.astro.Ephemeris.nearest_orbit_before}
+
+> def nearest_orbit_before(
+> self,
+> /,
+> epoch,
+> almanac
+> )
+
+Returns the nearest orbit before the provided time
+
+:type epoch: Epoch
+:type almanac: Almanac
+:rtype: Orbit
+
+
+##### Method `object_id` {#anise.astro.Ephemeris.object_id}
+
+> def object_id(
+> self,
+> /
+> )
+
+:rtype: str
+
+
+##### Method `orbit_at` {#anise.astro.Ephemeris.orbit_at}
+
+> def orbit_at(
+> self,
+> /,
+> epoch,
+> almanac
+> )
+
+Interpolate the ephemeris at the provided epoch, returning only the orbit.
+
+:type epoch: Epoch
+:type almanac: Almanac
+:rtype: Orbit
+
+
+##### Method `resample` {#anise.astro.Ephemeris.resample}
+
+> def resample(
+> self,
+> /,
+> ts,
+> almanac
+> )
+
+Resample this ephemeris, with covariance, at the provided time series
+
+:type ts: TimeSeries
+:type almanac: Almanac
+:rtype: Ephemeris
+
+
+##### Method `set_object_id` {#anise.astro.Ephemeris.set_object_id}
+
+> def set_object_id(
+> self,
+> /,
+> object_id
+> )
+
+:type object_id: str
+
+
+##### Method `start_epoch` {#anise.astro.Ephemeris.start_epoch}
+
+> def start_epoch(
+> self,
+> /
+> )
+
+:rtype: Epoch
+
+
+##### Method `transform` {#anise.astro.Ephemeris.transform}
+
+> def transform(
+> self,
+> /,
+> new_frame,
+> almanac
+> )
+
+Transforms this ephemeris into another frame, and rotates the covariance to that frame if the orientations are different.
+NOTE: The Nyquist-Shannon theorem is NOT applied here, so the new ephemeris may not be as precise as the original one.
+NOTE: If the orientations are different, the covariance will always be in the Inertial frame of the new frame.
+
+:type new_frame: Frame
+:type almanac: Almanac
+:rtype: Ephemeris
+
+
+##### Method `write_ccsds_oem` {#anise.astro.Ephemeris.write_ccsds_oem}
+
+> def write_ccsds_oem(
+> self,
+> /,
+> path,
+> originator=None,
+> object_name=None
+> )
+
+Exports this Ephemeris to CCSDS OEM at the provided path, optionally specifying an originator and/or an object name
+
+:type path: str
+:type originator: str, optional
+:type object_name: str, optional
+:rtype: None
+
+
+##### Method `write_spice_bsp` {#anise.astro.Ephemeris.write_spice_bsp}
+
+> def write_spice_bsp(
+> self,
+> /,
+> naif_id,
+> output_fname,
+> data_type
+> )
+
+Converts this ephemeris to SPICE BSP/SPK file in the provided data type, saved to the provided output_fname.
+
+:type naif_id: int
+:type output_fname: str
+:type data_type: DataType
+:rtype: None
+
+
+### Class `EphemerisRecord` {#anise.astro.EphemerisRecord}
+
+> class EphemerisRecord(
+> orbit,
+> covar
+> )
+
+An ephemeris record which can be inserted into an Ephemeris for export to SPICE BSP or CCSDS OEM.
+
+:type orbit: Orbit
+:type covar: Covariance
+
+
+#### Instance variables
+
+
+##### Variable `covar` {#anise.astro.EphemerisRecord.covar}
+
+Optional covariance associated with this orbit
+:rtype: Covariance
+
+
+##### Variable `orbit` {#anise.astro.EphemerisRecord.orbit}
+
+Orbit of this ephemeris entry
+:rtype: Orbit
+
+
+#### Methods
+
+
+##### Method `covar_in_frame` {#anise.astro.EphemerisRecord.covar_in_frame}
+
+> def covar_in_frame(
+> self,
+> /,
+> local_frame
+> )
+
+Returns the covariance in the desired orbit local frame, or None if this record does not define a covariance.
+
+:type local_frame: LocalFrame
+:rtype: Covariance
+
+
+##### Method `sigma_for` {#anise.astro.EphemerisRecord.sigma_for}
+
+> def sigma_for(
+> self,
+> /,
+> oe
+> )
+
+Returns the 1-sigma uncertainty (Standard Deviation) for a given orbital element.
+
+The result is in the unit of the parameter (e.g., km for SMA, degrees for angles).
+
+This method uses the [OrbitGrad] structure (Hyperdual numbers) to compute the
+Jacobian of the element with respect to the inertial Cartesian state, and then
+rotates the covariance into that hyperdual dual space: J * P * J^T.
+
+:type oe: OrbitalElement
+:rtype: float
+
+
+### Class `Frame` {#anise.astro.Frame}
+
+> class Frame(
+> ephemeris_id,
+> orientation_id,
+> mu_km3_s2=None,
+> shape=None
+> )
+
+A Frame uniquely defined by its ephemeris center and orientation. Refer to FrameDetail for frames combined with parameters.
+
+:type ephemeris_id: int
+:type orientation_id: int
+:type force_inertial: bool
+:type mu_km3_s2: float, optional
+:type shape: Ellipsoid, optional
+:type frozen_epoch: Epoch, optional
+:rtype: Frame
+
+
+#### Instance variables
+
+
+##### Variable `ephemeris_id` {#anise.astro.Frame.ephemeris_id}
+
+:rtype: int
+
+
+##### Variable `force_inertial` {#anise.astro.Frame.force_inertial}
+
+
+##### Variable `frozen_epoch` {#anise.astro.Frame.frozen_epoch}
+
+:rtype: Epoch
+
+
+##### Variable `orientation_id` {#anise.astro.Frame.orientation_id}
+
+:rtype: int
+
+
+##### Variable `shape` {#anise.astro.Frame.shape}
+
+:rtype: Ellipsoid
+
+
+#### Methods
+
+
+##### Method `ephem_origin_id_match` {#anise.astro.Frame.ephem_origin_id_match}
+
+> def ephem_origin_id_match(
+> self,
+> /,
+> other_id
+> )
+
+Returns true if the ephemeris origin is equal to the provided ID
+
+:type other_id: int
+:rtype: bool
+
+
+##### Method `ephem_origin_match` {#anise.astro.Frame.ephem_origin_match}
+
+> def ephem_origin_match(
+> self,
+> /,
+> other
+> )
+
+Returns true if the ephemeris origin is equal to the provided frame
+
+:type other: Frame
+:rtype: bool
-:type other: Frame
-:rtype: bool
-
##### Method `flattening` {#anise.astro.Frame.flattening}
> def flattening(
@@ -268,7 +1112,19 @@ Returns the flattening ratio (unitless)
:rtype: float
-
+
+##### Method `from_asn1` {#anise.astro.Frame.from_asn1}
+
+> def from_asn1(
+> data
+> )
+
+Decodes an ASN.1 DER encoded byte array into a Frame.
+
+:type data: bytes
+:rtype: Frame
+
+
##### Method `is_celestial` {#anise.astro.Frame.is_celestial}
> def is_celestial(
@@ -280,7 +1136,19 @@ Returns whether this is a celestial frame
:rtype: bool
-
+
+##### Method `is_dynamic` {#anise.astro.Frame.is_dynamic}
+
+> def is_dynamic(
+> self,
+> /
+> )
+
+Returns true if this is a dynamic frame, e.g. Mean/True of Date/Epoch
+
+:rtype: bool
+
+
##### Method `is_geodetic` {#anise.astro.Frame.is_geodetic}
> def is_geodetic(
@@ -292,7 +1160,7 @@ Returns whether this is a geodetic frame
:rtype: bool
-
+
##### Method `mean_equatorial_radius_km` {#anise.astro.Frame.mean_equatorial_radius_km}
> def mean_equatorial_radius_km(
@@ -302,164 +1170,403 @@ Returns whether this is a geodetic frame
Returns the mean equatorial radius in km, if defined
-:rtype: float
+:rtype: float
+
+
+##### Method `mu_km3_s2` {#anise.astro.Frame.mu_km3_s2}
+
+> def mu_km3_s2(
+> self,
+> /
+> )
+
+Returns the gravitational parameters of this frame, if defined
+
+:rtype: float
+
+
+##### Method `orient_origin_id_match` {#anise.astro.Frame.orient_origin_id_match}
+
+> def orient_origin_id_match(
+> self,
+> /,
+> other_id
+> )
+
+Returns true if the orientation origin is equal to the provided ID
+
+:type other_id: int
+:rtype: bool
+
+
+##### Method `orient_origin_match` {#anise.astro.Frame.orient_origin_match}
+
+> def orient_origin_match(
+> self,
+> /,
+> other
+> )
+
+Returns true if the orientation origin is equal to the provided frame
+
+:type other: Frame
+:rtype: bool
+
+
+##### Method `polar_radius_km` {#anise.astro.Frame.polar_radius_km}
+
+> def polar_radius_km(
+> self,
+> /
+> )
+
+Returns the polar radius in km, if defined
+
+:rtype: float
+
+
+##### Method `semi_major_radius_km` {#anise.astro.Frame.semi_major_radius_km}
+
+> def semi_major_radius_km(
+> self,
+> /
+> )
+
+Returns the semi major radius of the tri-axial ellipoid shape of this frame, if defined
+
+:rtype: float
+
+
+##### Method `strip` {#anise.astro.Frame.strip}
+
+> def strip(
+> self,
+> /
+> )
+
+Removes the graviational parameter and the shape information from this frame.
+Use this to prevent astrodynamical computations.
+
+:rtype: None
+
+
+##### Method `to_asn1` {#anise.astro.Frame.to_asn1}
+
+> def to_asn1(
+> self,
+> /
+> )
+
+Encodes this Frame into an ASN.1 DER encoded byte array.
+
+:rtype: bytes
+
+
+##### Method `with_ephem` {#anise.astro.Frame.with_ephem}
+
+> def with_ephem(
+> self,
+> /,
+> new_ephem_id
+> )
+
+Returns a copy of this Frame whose ephemeris ID is set to the provided ID
+
+:type new_ephem_id: int
+:rtype: Frame
+
+
+##### Method `with_mu_km3_s2` {#anise.astro.Frame.with_mu_km3_s2}
+
+> def with_mu_km3_s2(
+> self,
+> /,
+> mu_km3_s2
+> )
+
+Returns a copy of this frame with the graviational parameter set to the new value.
+
+:type mu_km3_s2: float
+:rtype: Frame
+
+
+##### Method `with_orient` {#anise.astro.Frame.with_orient}
+
+> def with_orient(
+> self,
+> /,
+> new_orient_id
+> )
+
+Returns a copy of this Frame whose orientation ID is set to the provided ID
+
+:type new_orient_id: int
+:rtype: Frame
+
+
+### Class `FrameUid` {#anise.astro.FrameUid}
+
+> class FrameUid(
+> ephemeris_id,
+> orientation_id
+> )
+
+A unique frame reference that only contains enough information to build the actual Frame object.
+It cannot be used for any computations, is it be used in any structure apart from error structures.
+
+:type ephemeris_id: int
+:type orientation_id: int
+
+
+#### Instance variables
+
+
+##### Variable `force_inertial` {#anise.astro.FrameUid.force_inertial}
+
+
+##### Variable `frozen_epoch` {#anise.astro.FrameUid.frozen_epoch}
+
+:rtype: Epoch
+
+
+### Class `LocalFrame` {#anise.astro.LocalFrame}
+
+> class LocalFrame
+
+
+#### Class variables
+
+
+##### Variable `Inertial` {#anise.astro.LocalFrame.Inertial}
+
+
+##### Variable `RCN` {#anise.astro.LocalFrame.RCN}
+
+
+##### Variable `RIC` {#anise.astro.LocalFrame.RIC}
+
+
+##### Variable `VNC` {#anise.astro.LocalFrame.VNC}
+
+
+### Class `Location` {#anise.astro.Location}
+
+> class Location(
+> latitude_deg,
+> longitude_deg,
+> height_km,
+> frame,
+> terrain_mask,
+> terrain_mask_ignored
+> )
+
+Location is defined by its latitude, longitude, height above the geoid, mean angular rotation of the geoid, and a frame UID.
+If the location includes a terrain mask, it will be used for obstruction checks when computing azimuth and elevation.
+**Note:** The mean Earth angular velocity is 0.004178079012116429 deg/s.
+
+:type latitude_deg: float
+:type longitude_deg: float
+:type height_km: float
+:type frame: FrameUid
+:type terrain_mask: list
+:type terrain_mask_ignored: bool
+
+
+#### Instance variables
+
+
+##### Variable `height_km` {#anise.astro.Location.height_km}
+
+:rtype: float
+
+
+##### Variable `latitude_deg` {#anise.astro.Location.latitude_deg}
+
+:rtype: float
+
+
+##### Variable `longitude_deg` {#anise.astro.Location.longitude_deg}
+
+:rtype: float
+
+
+##### Variable `terrain_mask` {#anise.astro.Location.terrain_mask}
+
+:rtype: list
+
+
+##### Variable `terrain_mask_ignored` {#anise.astro.Location.terrain_mask_ignored}
+
+:rtype: bool
+
+
+#### Methods
+
+
+##### Method `elevation_mask_at_azimuth_deg` {#anise.astro.Location.elevation_mask_at_azimuth_deg}
+
+> def elevation_mask_at_azimuth_deg(
+> self,
+> /,
+> azimuth_deg
+> )
+
+Returns the elevation mask at the provided azimuth, does NOT account for whether the mask is ignored or not.
+
+:type azimuth_deg: float
+:rtype: float
+
+
+##### Method `from_dhall` {#anise.astro.Location.from_dhall}
+
+> def from_dhall(
+> repr
+> )
+
+Loads a Location from its Dhall representation
+
+:type repr: str
+:rtype: Location
+
-
-##### Method `mu_km3_s2` {#anise.astro.Frame.mu_km3_s2}
+##### Method `to_dhall` {#anise.astro.Location.to_dhall}
-> def mu_km3_s2(
+> def to_dhall(
> self,
> /
> )
-Returns the gravitational parameters of this frame, if defined
+Returns the Dhall representation of this Location
-:rtype: float
+:rtype: str
-
-##### Method `orient_origin_id_match` {#anise.astro.Frame.orient_origin_id_match}
-> def orient_origin_id_match(
-> self,
-> /,
-> other_id
+### Class `Mass` {#anise.astro.Mass}
+
+> class Mass(
+> dry_mass_kg,
+> prop_mass_kg=None,
+> extra_mass_kg=None
> )
-Returns true if the orientation origin is equal to the provided ID
+Defines a spacecraft mass a the sum of the dry (structural) mass and the propellant mass, both in kilogram
-:type other_id: int
-:rtype: bool
-
-##### Method `orient_origin_match` {#anise.astro.Frame.orient_origin_match}
+#### Instance variables
-> def orient_origin_match(
-> self,
-> /,
-> other
-> )
-Returns true if the orientation origin is equal to the provided frame
+##### Variable `dry_mass_kg` {#anise.astro.Mass.dry_mass_kg}
-:type other: Frame
-:rtype: bool
+Structural mass of the spacecraft, in kg
+:rtype: float
-
-##### Method `polar_radius_km` {#anise.astro.Frame.polar_radius_km}
-> def polar_radius_km(
-> self,
-> /
-> )
+##### Variable `extra_mass_kg` {#anise.astro.Mass.extra_mass_kg}
-Returns the polar radius in km, if defined
+Extra mass like unusable propellant mass of the spacecraft, in kg
+:rtype: float
+
+##### Variable `prop_mass_kg` {#anise.astro.Mass.prop_mass_kg}
+
+Propellant mass of the spacecraft, in kg
:rtype: float
-
-##### Method `semi_major_radius_km` {#anise.astro.Frame.semi_major_radius_km}
-> def semi_major_radius_km(
+#### Methods
+
+
+##### Method `abs` {#anise.astro.Mass.abs}
+
+> def abs(
> self,
> /
> )
-Returns the semi major radius of the tri-axial ellipoid shape of this frame, if defined
+Returns a Mass structure that is guaranteed to be physically correct
+:rtype: Mass
-:rtype: float
-
-##### Method `strip` {#anise.astro.Frame.strip}
+##### Method `from_asn1` {#anise.astro.Mass.from_asn1}
-> def strip(
-> self,
-> /
+> def from_asn1(
+> data
> )
-Removes the graviational parameter and the shape information from this frame.
-Use this to prevent astrodynamical computations.
+Decodes an ASN.1 DER encoded byte array into a Mass object.
-:rtype: None
+:type data: bytes
+:rtype: Mass
-
-##### Method `with_ephem` {#anise.astro.Frame.with_ephem}
-> def with_ephem(
+##### Method `is_valid` {#anise.astro.Mass.is_valid}
+
+> def is_valid(
> self,
-> /,
-> new_ephem_id
+> /
> )
-Returns a copy of this Frame whose ephemeris ID is set to the provided ID
+Returns true if all the masses are greater or equal to zero
+:rtype: bool
-:type new_ephem_id: int
-:rtype: Frame
-
-##### Method `with_mu_km3_s2` {#anise.astro.Frame.with_mu_km3_s2}
+##### Method `to_asn1` {#anise.astro.Mass.to_asn1}
-> def with_mu_km3_s2(
+> def to_asn1(
> self,
-> /,
-> mu_km3_s2
+> /
> )
-Returns a copy of this frame with the graviational parameter set to the new value.
+Encodes this Mass object into an ASN.1 DER encoded byte array.
-:type mu_km3_s2: float
-:rtype: Frame
+:rtype: bytes
-
-##### Method `with_orient` {#anise.astro.Frame.with_orient}
-> def with_orient(
+##### Method `total_mass_kg` {#anise.astro.Mass.total_mass_kg}
+
+> def total_mass_kg(
> self,
-> /,
-> new_orient_id
+> /
> )
-Returns a copy of this Frame whose orientation ID is set to the provided ID
+Returns the total mass in kg
+:rtype: float
-:type new_orient_id: int
-:rtype: Frame
-
### Class `Occultation` {#anise.astro.Occultation}
-> class Occultation(
-> ...
-> )
+> class Occultation
-Stores the result of an occultation computation with the occulation percentage
+Stores the result of an occultation computation with the occultation percentage
Refer to the [MathSpec](https://nyxspace.com/nyxspace/MathSpec/celestial/eclipse/) for modeling details.
-
+
#### Instance variables
-
+
##### Variable `back_frame` {#anise.astro.Occultation.back_frame}
:rtype: Frame
-
+
##### Variable `epoch` {#anise.astro.Occultation.epoch}
:rtype: Epoch
-
+
##### Variable `front_frame` {#anise.astro.Occultation.front_frame}
:rtype: Frame
-
+
##### Variable `percentage` {#anise.astro.Occultation.percentage}
:rtype: float
-
+
#### Methods
-
+
##### Method `factor` {#anise.astro.Occultation.factor}
> def factor(
@@ -471,7 +1578,7 @@ Returns the percentage as a factor between 0 and 1
:rtype: float
-
+
##### Method `is_eclipse_computation` {#anise.astro.Occultation.is_eclipse_computation}
> def is_eclipse_computation(
@@ -483,7 +1590,7 @@ Returns true if the back object is the Sun, false otherwise
:rtype: bool
-
+
##### Method `is_obstructed` {#anise.astro.Occultation.is_obstructed}
> def is_obstructed(
@@ -495,7 +1602,7 @@ Returns true if the occultation percentage is greater than or equal 99.999%
:rtype: bool
-
+
##### Method `is_partial` {#anise.astro.Occultation.is_partial}
> def is_partial(
@@ -507,7 +1614,7 @@ Returns true if neither occulted nor visible (i.e. penumbra for solar eclipsing)
:rtype: bool
-
+
##### Method `is_visible` {#anise.astro.Occultation.is_visible}
> def is_visible(
@@ -519,18 +1626,11 @@ Returns true if the occultation percentage is less than or equal 0.001%
:rtype: bool
-
+
### Class `Orbit` {#anise.astro.Orbit}
> class Orbit(
-> x_km,
-> y_km,
-> z_km,
-> vx_km_s,
-> vy_km_s,
-> vz_km_s,
-> epoch,
-> frame
+> *args
> )
Defines a Cartesian state in a given frame at a given epoch in a given time scale. Radius data is expressed in kilometers. Velocity data is expressed in kilometers per second.
@@ -538,69 +1638,56 @@ Regardless of the constructor used, this struct stores all the state information
Unless noted otherwise, algorithms are from GMAT 2016a [StateConversionUtil.cpp](https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/util/StateConversionUtil.cpp).
-:type x_km: float
-:type y_km: float
-:type z_km: float
-:type vx_km_s: float
-:type vy_km_s: float
-:type vz_km_s: float
-:type epoch: Epoch
-:type frame: Frame
+:type args: tuples
:rtype: Orbit
-
+
#### Instance variables
-
+
##### Variable `epoch` {#anise.astro.Orbit.epoch}
:rtype: Epoch
-
+
##### Variable `frame` {#anise.astro.Orbit.frame}
:rtype: Frame
-
+
##### Variable `vx_km_s` {#anise.astro.Orbit.vx_km_s}
:rtype: float
-
+
##### Variable `vy_km_s` {#anise.astro.Orbit.vy_km_s}
:rtype: float
-
-##### Variable `vz_km` {#anise.astro.Orbit.vz_km}
-:type vz_km_s: float
-:rtype: None
-
-
##### Variable `vz_km_s` {#anise.astro.Orbit.vz_km_s}
:rtype: float
-
+
##### Variable `x_km` {#anise.astro.Orbit.x_km}
:rtype: float
-
+
##### Variable `y_km` {#anise.astro.Orbit.y_km}
:rtype: float
-
+
##### Variable `z_km` {#anise.astro.Orbit.z_km}
:rtype: float
-
+
#### Methods
-
+
##### Method `abs_difference` {#anise.astro.Orbit.abs_difference}
> def abs_difference(
@@ -615,7 +1702,7 @@ Raises an error if the frames do not match (epochs do not need to match).
:type other: Orbit
:rtype: typing.Tuple
-
+
##### Method `abs_pos_diff_km` {#anise.astro.Orbit.abs_pos_diff_km}
> def abs_pos_diff_km(
@@ -630,7 +1717,7 @@ Raises an error if the frames do not match (epochs do not need to match).
:type other: Orbit
:rtype: float
-
+
##### Method `abs_vel_diff_km_s` {#anise.astro.Orbit.abs_vel_diff_km_s}
> def abs_vel_diff_km_s(
@@ -645,7 +1732,7 @@ Raises an error if the frames do not match (epochs do not need to match).
:type other: Orbit
:rtype: float
-
+
##### Method `add_aop_deg` {#anise.astro.Orbit.add_aop_deg}
> def add_aop_deg(
@@ -659,7 +1746,7 @@ Returns a copy of the state with a provided AOP added to the current one
:type delta_aop_deg: float
:rtype: Orbit
-
+
##### Method `add_apoapsis_periapsis_km` {#anise.astro.Orbit.add_apoapsis_periapsis_km}
> def add_apoapsis_periapsis_km(
@@ -675,7 +1762,7 @@ Returns a copy of this state with the provided apoasis and periapsis added to th
:type delta_rp_km: float
:rtype: Orbit
-
+
##### Method `add_ecc` {#anise.astro.Orbit.add_ecc}
> def add_ecc(
@@ -689,7 +1776,7 @@ Returns a copy of the state with a provided ECC added to the current one
:type delta_ecc: float
:rtype: Orbit
-
+
##### Method `add_inc_deg` {#anise.astro.Orbit.add_inc_deg}
> def add_inc_deg(
@@ -701,9 +1788,9 @@ Returns a copy of the state with a provided ECC added to the current one
Returns a copy of the state with a provided INC added to the current one
:type delta_inc_deg: float
-:rtype: None
+:rtype: Orbit
+
-
##### Method `add_raan_deg` {#anise.astro.Orbit.add_raan_deg}
> def add_raan_deg(
@@ -717,7 +1804,7 @@ Returns a copy of the state with a provided RAAN added to the current one
:type delta_raan_deg: float
:rtype: Orbit
-
+
##### Method `add_sma_km` {#anise.astro.Orbit.add_sma_km}
> def add_sma_km(
@@ -731,7 +1818,7 @@ Returns a copy of the state with a provided SMA added to the current one
:type delta_sma_km: float
:rtype: Orbit
-
+
##### Method `add_ta_deg` {#anise.astro.Orbit.add_ta_deg}
> def add_ta_deg(
@@ -745,7 +1832,7 @@ Returns a copy of the state with a provided TA added to the current one
:type delta_ta_deg: float
:rtype: Orbit
-
+
##### Method `altitude_km` {#anise.astro.Orbit.altitude_km}
> def altitude_km(
@@ -757,7 +1844,7 @@ Returns the altitude in km
:rtype: float
-
+
##### Method `aol_deg` {#anise.astro.Orbit.aol_deg}
> def aol_deg(
@@ -772,7 +1859,19 @@ instead of relying on the ill-defined true anomaly.
:rtype: float
-
+
+##### Method `aop_brouwer_short_deg` {#anise.astro.Orbit.aop_brouwer_short_deg}
+
+> def aop_brouwer_short_deg(
+> self,
+> /
+> )
+
+Returns the Brouwer-short mean Argument of Perigee in degrees.
+
+:rtype: float
+
+
##### Method `aop_deg` {#anise.astro.Orbit.aop_deg}
> def aop_deg(
@@ -784,7 +1883,7 @@ Returns the argument of periapsis in degrees
:rtype: float
-
+
##### Method `apoapsis_altitude_km` {#anise.astro.Orbit.apoapsis_altitude_km}
> def apoapsis_altitude_km(
@@ -796,7 +1895,7 @@ Returns the altitude of apoapsis (or apogee around Earth), in kilometers.
:rtype: float
-
+
##### Method `apoapsis_km` {#anise.astro.Orbit.apoapsis_km}
> def apoapsis_km(
@@ -808,7 +1907,7 @@ Returns the radius of apoapsis (or apogee around Earth), in kilometers.
:rtype: float
-
+
##### Method `at_epoch` {#anise.astro.Orbit.at_epoch}
> def at_epoch(
@@ -817,16 +1916,16 @@ Returns the radius of apoapsis (or apogee around Earth), in kilometers.
> new_epoch
> )
-Adjusts the true anomaly of this orbit using the mean anomaly.
+Adjusts the equinoctial mean longitude this orbit via the mean motion.
##### Astrodynamics note
This is not a true propagation of the orbit. This is akin to a two body propagation ONLY without any other force models applied.
-Use Nyx for high fidelity propagation.
+Use Nyx for high fidelity propagation. This implementation uses equinoctial elements and should be well behaved for circular equatorial orbits.
:type new_epoch: Epoch
:rtype: Orbit
-
+
##### Method `c3_km2_s2` {#anise.astro.Orbit.c3_km2_s2}
> def c3_km2_s2(
@@ -838,7 +1937,7 @@ Returns the $C_3$ of this orbit in km^2/s^2
:rtype: float
-
+
##### Method `cartesian_pos_vel` {#anise.astro.Orbit.cartesian_pos_vel}
> def cartesian_pos_vel(
@@ -849,9 +1948,9 @@ Returns the $C_3$ of this orbit in km^2/s^2
Returns this state as a Cartesian vector of size 6 in [km, km, km, km/s, km/s, km/s]
Note that the time is **not** returned in the vector.
-:rtype: numpy.array
+:rtype: numpy.ndarray
+
-
##### Method `dcm3x3_from_rcn_to_inertial` {#anise.astro.Orbit.dcm3x3_from_rcn_to_inertial}
> def dcm3x3_from_rcn_to_inertial(
@@ -872,7 +1971,7 @@ If the stattion is NOT in an inertial frame, then this computation is INVALID.
:rtype: DCM
-
+
##### Method `dcm3x3_from_ric_to_inertial` {#anise.astro.Orbit.dcm3x3_from_ric_to_inertial}
> def dcm3x3_from_ric_to_inertial(
@@ -893,7 +1992,7 @@ If the state is NOT in an inertial frame, then this computation is INVALID.
:rtype: DCM
-
+
##### Method `dcm3x3_from_topocentric_to_body_fixed` {#anise.astro.Orbit.dcm3x3_from_topocentric_to_body_fixed}
> def dcm3x3_from_topocentric_to_body_fixed(
@@ -914,7 +2013,7 @@ to body fixed.
:rtype: DCM
-
+
##### Method `dcm3x3_from_vnc_to_inertial` {#anise.astro.Orbit.dcm3x3_from_vnc_to_inertial}
> def dcm3x3_from_vnc_to_inertial(
@@ -935,7 +2034,7 @@ If the stattion is NOT in an inertial frame, then this computation is INVALID.
:rtype: DCM
-
+
##### Method `dcm_from_rcn_to_inertial` {#anise.astro.Orbit.dcm_from_rcn_to_inertial}
> def dcm_from_rcn_to_inertial(
@@ -960,7 +2059,7 @@ Further note that most astrodynamics tools do *not* account for the time derivat
:rtype: DCM
-
+
##### Method `dcm_from_ric_to_inertial` {#anise.astro.Orbit.dcm_from_ric_to_inertial}
> def dcm_from_ric_to_inertial(
@@ -988,13 +2087,12 @@ Further note that most astrodynamics tools do *not* account for the time derivat
:rtype: DCM
-
+
##### Method `dcm_from_topocentric_to_body_fixed` {#anise.astro.Orbit.dcm_from_topocentric_to_body_fixed}
> def dcm_from_topocentric_to_body_fixed(
> self,
-> /,
-> _from
+> /
> )
Builds the rotation matrix that rotates from the topocentric frame (SEZ) into the body fixed frame of this state.
@@ -1012,10 +2110,9 @@ rotation matrix from the topocentric frame (SEZ) to body fixed frame.
In the GMAT MathSpec notation, R_{IF} is the DCM from body fixed to inertial. Similarly, R{FT} is from topocentric
to body fixed.
-:type _from: float
:rtype: DCM
-
+
##### Method `dcm_from_vnc_to_inertial` {#anise.astro.Orbit.dcm_from_vnc_to_inertial}
> def dcm_from_vnc_to_inertial(
@@ -1041,7 +2138,21 @@ Further note that most astrodynamics tools do *not* account for the time derivat
:rtype: DCM
-
+
+##### Method `dcm_to_inertial` {#anise.astro.Orbit.dcm_to_inertial}
+
+> def dcm_to_inertial(
+> self,
+> /,
+> local_frame
+> )
+
+Returns the DCM to rotate this orbit from the provided local frame to the inertial frame.
+
+:type local_frame: LocalFrame
+:rtype: DCM
+
+
##### Method `declination_deg` {#anise.astro.Orbit.declination_deg}
> def declination_deg(
@@ -1053,7 +2164,7 @@ Returns the declination of this orbit in degrees
:rtype: float
-
+
##### Method `distance_to_km` {#anise.astro.Orbit.distance_to_km}
> def distance_to_km(
@@ -1067,7 +2178,7 @@ Returns the distance in kilometers between this state and another state, if both
:type other: Orbit
:rtype: float
-
+
##### Method `duration_to_radius` {#anise.astro.Orbit.duration_to_radius}
> def duration_to_radius(
@@ -1098,7 +2209,7 @@ two-body dynamics and considers the direction of motion.
:type radius_km: float
:rtype: Duration
-
+
##### Method `ea_deg` {#anise.astro.Orbit.ea_deg}
> def ea_deg(
@@ -1112,7 +2223,7 @@ This is a conversion from GMAT's StateConversionUtil::TrueToEccentricAnomaly
:rtype: float
-
+
##### Method `ecc` {#anise.astro.Orbit.ecc}
> def ecc(
@@ -1124,37 +2235,133 @@ Returns the eccentricity (no unit)
:rtype: float
-
-##### Method `energy_km2_s2` {#anise.astro.Orbit.energy_km2_s2}
-> def energy_km2_s2(
+##### Method `ecc_brouwer_short` {#anise.astro.Orbit.ecc_brouwer_short}
+
+> def ecc_brouwer_short(
+> self,
+> /
+> )
+
+Returns the Brouwer-short mean eccentricity.
+
+:rtype: float
+
+
+##### Method `energy_km2_s2` {#anise.astro.Orbit.energy_km2_s2}
+
+> def energy_km2_s2(
+> self,
+> /
+> )
+
+Returns the specific mechanical energy in km^2/s^2
+
+:rtype: float
+
+
+##### Method `eq_within` {#anise.astro.Orbit.eq_within}
+
+> def eq_within(
+> self,
+> /,
+> other,
+> radial_tol_km,
+> velocity_tol_km_s
+> )
+
+Returns whether this orbit and another are equal within the specified radial and velocity absolute tolerances
+
+:type other: Orbit
+:type radial_tol_km: float
+:type velocity_tol_km_s: float
+:rtype: bool
+
+
+##### Method `equinoctial_a_km` {#anise.astro.Orbit.equinoctial_a_km}
+
+> def equinoctial_a_km(
+> self,
+> /
+> )
+
+Returns the equinoctial semi-major axis (a) in km.
+
+:rtype: float
+
+
+##### Method `equinoctial_elements` {#anise.astro.Orbit.equinoctial_elements}
+
+> def equinoctial_elements(
+> self,
+> /
+> )
+
+Returns the six equinoctial elements in order: sma (km), h, k, p, q, lambda (deg)
+
+:rtype: list[float]
+
+
+##### Method `equinoctial_h` {#anise.astro.Orbit.equinoctial_h}
+
+> def equinoctial_h(
+> self,
+> /
+> )
+
+Returns the equinoctial element h (ecc * sin(aop + raan)).
+
+:rtype: float
+
+
+##### Method `equinoctial_k` {#anise.astro.Orbit.equinoctial_k}
+
+> def equinoctial_k(
+> self,
+> /
+> )
+
+Returns the equinoctial element k (ecc * cos(aop + raan)).
+
+:rtype: float
+
+
+##### Method `equinoctial_lambda_mean_deg` {#anise.astro.Orbit.equinoctial_lambda_mean_deg}
+
+> def equinoctial_lambda_mean_deg(
+> self,
+> /
+> )
+
+Returns the equinoctial mean longitude (lambda = raan + aop + ma) in degrees.
+
+:rtype: float
+
+
+##### Method `equinoctial_p` {#anise.astro.Orbit.equinoctial_p}
+
+> def equinoctial_p(
> self,
> /
> )
-Returns the specific mechanical energy in km^2/s^2
+Returns the equinoctial element p (sin(inc/2) * sin(raan)).
:rtype: float
-
-##### Method `eq_within` {#anise.astro.Orbit.eq_within}
-> def eq_within(
+##### Method `equinoctial_q` {#anise.astro.Orbit.equinoctial_q}
+
+> def equinoctial_q(
> self,
-> /,
-> other,
-> radial_tol_km,
-> velocity_tol_km_s
+> /
> )
-Returns whether this orbit and another are equal within the specified radial and velocity absolute tolerances
+Returns the equinoctial element q (sin(inc/2) * cos(raan)).
+
+:rtype: float
-:type other: Orbit
-:type radial_tol_km: float
-:type velocity_tol_km_s: float
-:rtype: bool
-
##### Method `fpa_deg` {#anise.astro.Orbit.fpa_deg}
> def fpa_deg(
@@ -1166,7 +2373,19 @@ Returns the flight path angle in degrees
:rtype: float
-
+
+##### Method `from_asn1` {#anise.astro.Orbit.from_asn1}
+
+> def from_asn1(
+> data
+> )
+
+Decodes an ASN.1 DER encoded byte array into a CartesianState (Orbit).
+
+:type data: bytes
+:rtype: Orbit
+
+
##### Method `from_cartesian` {#anise.astro.Orbit.from_cartesian}
> def from_cartesian(
@@ -1194,7 +2413,55 @@ Creates a new Cartesian state in the provided frame at the provided Epoch.
:type frame: Frame
:rtype: Orbit
-
+
+##### Method `from_cartesian_npy` {#anise.astro.Orbit.from_cartesian_npy}
+
+> def from_cartesian_npy(
+> pos_vel,
+> epoch,
+> frame
+> )
+
+Creates a new Cartesian state from a numpy array, an epoch, and a frame.
+
+**Units:** km, km, km, km/s, km/s, km/s
+
+:type pos_vel: np.array
+:type epoch: Epoch
+:type frame: Frame
+:rtype: Orbit
+
+
+##### Method `from_equinoctial` {#anise.astro.Orbit.from_equinoctial}
+
+> def from_equinoctial(
+> sma_km,
+> h,
+> k,
+> p,
+> q,
+> lambda_deg,
+> epoch,
+> frame
+> )
+
+Attempts to create a new Orbit from the Equinoctial orbital elements.
+
+##### Implementation notes
+Note that this function computes the Keplerian elements from the equinoctial and then
+calls the try_keplerian_mean_anomaly initializer.
+
+:type sma_km: float
+:type h: float
+:type k: float
+:type p: float
+:type q: float
+:type lambda_deg: float
+:type epoch: Epoch
+:type frame: Frame
+:rtype: Orbit
+
+
##### Method `from_keplerian` {#anise.astro.Orbit.from_keplerian}
> def from_keplerian(
@@ -1226,7 +2493,7 @@ One should expect these errors to be on the order of 1e-12.
:type frame: Frame
:rtype: Orbit
-
+
##### Method `from_keplerian_altitude` {#anise.astro.Orbit.from_keplerian_altitude}
> def from_keplerian_altitude(
@@ -1252,7 +2519,7 @@ Creates a new Orbit from the provided semi-major axis altitude in kilometers
:type frame: Frame
:rtype: Orbit
-
+
##### Method `from_keplerian_apsis_altitude` {#anise.astro.Orbit.from_keplerian_apsis_altitude}
> def from_keplerian_apsis_altitude(
@@ -1278,7 +2545,7 @@ Creates a new Orbit from the provided altitudes of apoapsis and periapsis, in ki
:type frame: Frame
:rtype: Orbit
-
+
##### Method `from_keplerian_apsis_radii` {#anise.astro.Orbit.from_keplerian_apsis_radii}
> def from_keplerian_apsis_radii(
@@ -1304,7 +2571,7 @@ Attempts to create a new Orbit from the provided radii of apoapsis and periapsis
:type frame: Frame
:rtype: Orbit
-
+
##### Method `from_keplerian_mean_anomaly` {#anise.astro.Orbit.from_keplerian_mean_anomaly}
> def from_keplerian_mean_anomaly(
@@ -1335,33 +2602,62 @@ The conversion is from GMAT's MeanToTrueAnomaly function, transliterated origina
:type frame: Frame
:rtype: Orbit
-
+
##### Method `from_latlongalt` {#anise.astro.Orbit.from_latlongalt}
> def from_latlongalt(
> latitude_deg,
> longitude_deg,
> height_km,
-> angular_velocity,
> epoch,
> frame
> )
-Creates a new Orbit from the latitude (φ), longitude (λ) and height (in km) with respect to the frame's ellipsoid given the angular velocity.
+Creates a new Orbit from the latitude (φ), longitude (λ) and height (in km) with respect to the frame's ellipsoid, and with ZERO angular velocity in this frame.
+Use this initializer for creating a fixed point in the ITRF93 frame for example: the correct angular velocity will be applied when transforming this to EME2000 for example.
+
+Refer to [try_latlongalt_omega] if you need to build a fixed point with a non-zero angular velocity in the definition frame.
+
+NOTE: This computation differs from the spherical coordinates because we consider the flattening of body.
+Reference: G. Xu and Y. Xu, "GPS", DOI 10.1007/978-3-662-50367-6_2, 2016
+
+:type latitude_deg: float
+:type longitude_deg: float
+:type height_km: float
+:type epoch: Epoch
+:type frame: Frame
+:rtype: Orbit
+
+
+##### Method `from_latlongalt_omega` {#anise.astro.Orbit.from_latlongalt_omega}
+
+> def from_latlongalt_omega(
+> latitude_deg,
+> longitude_deg,
+> height_km,
+> angular_velocity_rad_s,
+> epoch,
+> frame
+> )
+
+Creates a new Orbit from the latitude (φ), longitude (λ) and height (in km) with respect to the frame's ellipsoid given the angular velocity vector.
+NOTE: Only specify the angular velocity if there's an EXTRA angular velocity of the lat/long/alt point in the provided frame.
+
+Consider using the [Almanac]'s [angular_velocity_wrt_j2000_rad_s] function or [angular_velocity_rad_s] to retrieve the exact angular velocity vector between two orientations.
+Example: build a lat/long/alt point referenced in the ITRF93 frame but by specifying the Frame as the EME2000 frame and providing the angular velocity between the ITRF93 and EME2000 frame at the desired time.
-**Units:** degrees, degrees, km, rad/s
NOTE: This computation differs from the spherical coordinates because we consider the flattening of body.
Reference: G. Xu and Y. Xu, "GPS", DOI 10.1007/978-3-662-50367-6_2, 2016
:type latitude_deg: float
:type longitude_deg: float
:type height_km: float
-:type angular_velocity: float
+:type angular_velocity_rad_s: np.array
:type epoch: Epoch
:type frame: Frame
:rtype: Orbit
-
+
##### Method `height_km` {#anise.astro.Orbit.height_km}
> def height_km(
@@ -1375,7 +2671,7 @@ Reference: Vallado, 4th Ed., Algorithm 12 page 172.
:rtype: float
-
+
##### Method `hmag` {#anise.astro.Orbit.hmag}
> def hmag(
@@ -1387,7 +2683,7 @@ Returns the norm of the orbital momentum
:rtype: float
-
+
##### Method `hx` {#anise.astro.Orbit.hx}
> def hx(
@@ -1399,7 +2695,7 @@ Returns the orbital momentum value on the X axis
:rtype: float
-
+
##### Method `hy` {#anise.astro.Orbit.hy}
> def hy(
@@ -1411,7 +2707,7 @@ Returns the orbital momentum value on the Y axis
:rtype: float
-
+
##### Method `hyperbolic_anomaly_deg` {#anise.astro.Orbit.hyperbolic_anomaly_deg}
> def hyperbolic_anomaly_deg(
@@ -1424,7 +2720,7 @@ Returns an error if the orbit is not hyperbolic.
:rtype: float
-
+
##### Method `hz` {#anise.astro.Orbit.hz}
> def hz(
@@ -1436,7 +2732,19 @@ Returns the orbital momentum value on the Z axis
:rtype: float
-
+
+##### Method `inc_brouwer_short_deg` {#anise.astro.Orbit.inc_brouwer_short_deg}
+
+> def inc_brouwer_short_deg(
+> self,
+> /
+> )
+
+Returns the Brouwer-short mean inclination in degrees.
+
+:rtype: float
+
+
##### Method `inc_deg` {#anise.astro.Orbit.inc_deg}
> def inc_deg(
@@ -1448,7 +2756,7 @@ Returns the inclination in degrees
:rtype: float
-
+
##### Method `is_brouwer_short_valid` {#anise.astro.Orbit.is_brouwer_short_valid}
> def is_brouwer_short_valid(
@@ -1466,7 +2774,7 @@ main celestial body around which the state is defined (GMAT does perform this ve
:rtype: bool
-
+
##### Method `latitude_deg` {#anise.astro.Orbit.latitude_deg}
> def latitude_deg(
@@ -1481,7 +2789,7 @@ This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this f
:rtype: float
-
+
##### Method `latlongalt` {#anise.astro.Orbit.latlongalt}
> def latlongalt(
@@ -1496,7 +2804,7 @@ This uses the Heikkinen procedure, which is not iterative. The results match Val
:rtype: typing.Tuple
-
+
##### Method `light_time` {#anise.astro.Orbit.light_time}
> def light_time(
@@ -1508,7 +2816,7 @@ Returns the light time duration between this object and the origin of its refere
:rtype: Duration
-
+
##### Method `longitude_360_deg` {#anise.astro.Orbit.longitude_360_deg}
> def longitude_360_deg(
@@ -1523,7 +2831,7 @@ This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this f
:rtype: float
-
+
##### Method `longitude_deg` {#anise.astro.Orbit.longitude_deg}
> def longitude_deg(
@@ -1538,7 +2846,7 @@ This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this f
:rtype: float
-
+
##### Method `ltan_deg` {#anise.astro.Orbit.ltan_deg}
> def ltan_deg(
@@ -1550,7 +2858,19 @@ Returns the Longitude of the Ascending Node (LTAN), or an error of equatorial or
:rtype: float
-
+
+##### Method `ma_brouwer_short_deg` {#anise.astro.Orbit.ma_brouwer_short_deg}
+
+> def ma_brouwer_short_deg(
+> self,
+> /
+> )
+
+Returns the Brouwer-short mean Mean Anomaly in degrees.
+
+:rtype: float
+
+
##### Method `ma_deg` {#anise.astro.Orbit.ma_deg}
> def ma_deg(
@@ -1564,7 +2884,7 @@ This is a conversion from GMAT's StateConversionUtil::TrueToMeanAnomaly
:rtype: float
-
+
##### Method `mean_motion_deg_s` {#anise.astro.Orbit.mean_motion_deg_s}
> def mean_motion_deg_s(
@@ -1576,7 +2896,7 @@ Returns the mean motion in degrees per seconds
:rtype: float
-
+
##### Method `periapsis_altitude_km` {#anise.astro.Orbit.periapsis_altitude_km}
> def periapsis_altitude_km(
@@ -1588,7 +2908,7 @@ Returns the altitude of periapsis (or perigee around Earth), in kilometers.
:rtype: float
-
+
##### Method `periapsis_km` {#anise.astro.Orbit.periapsis_km}
> def periapsis_km(
@@ -1600,7 +2920,7 @@ Returns the radius of periapsis (or perigee around Earth), in kilometers.
:rtype: float
-
+
##### Method `period` {#anise.astro.Orbit.period}
> def period(
@@ -1608,11 +2928,23 @@ Returns the radius of periapsis (or perigee around Earth), in kilometers.
> /
> )
-Returns the period in seconds
+Returns the period
:rtype: Duration
-
+
+##### Method `raan_brouwer_short_deg` {#anise.astro.Orbit.raan_brouwer_short_deg}
+
+> def raan_brouwer_short_deg(
+> self,
+> /
+> )
+
+Returns the Brouwer-short mean Right Ascension of the Ascending Node in degrees.
+
+:rtype: float
+
+
##### Method `raan_deg` {#anise.astro.Orbit.raan_deg}
> def raan_deg(
@@ -1624,7 +2956,19 @@ Returns the right ascension of the ascending node in degrees
:rtype: float
-
+
+##### Method `radius_km` {#anise.astro.Orbit.radius_km}
+
+> def radius_km(
+> self,
+> /
+> )
+
+radius vector in km
+
+:rtype: np.array
+
+
##### Method `rel_difference` {#anise.astro.Orbit.rel_difference}
> def rel_difference(
@@ -1640,7 +2984,7 @@ Raises an error if the frames do not match, if the position is zero or the veloc
:type other: Orbit
:rtype: typing.Tuple
-
+
##### Method `rel_pos_diff` {#anise.astro.Orbit.rel_pos_diff}
> def rel_pos_diff(
@@ -1657,7 +3001,7 @@ Raises an error if the frames do not match or (epochs do not need to match).
:type other: Orbit
:rtype: float
-
+
##### Method `rel_vel_diff` {#anise.astro.Orbit.rel_vel_diff}
> def rel_vel_diff(
@@ -1672,7 +3016,7 @@ Raises an error if the frames do not match (epochs do not need to match).
:type other: Orbit
:rtype: float
-
+
##### Method `ric_difference` {#anise.astro.Orbit.ric_difference}
> def ric_difference(
@@ -1685,16 +3029,15 @@ Returns a Cartesian state representing the RIC difference between self and other
Refer to dcm_from_ric_to_inertial for details on the RIC frame.
##### Algorithm
-1. Compute the RIC DCM of self
-2. Rotate self into the RIC frame
-3. Rotation other into the RIC frame
-4. Compute the difference between these two states
-5. Strip the astrodynamical information from the frame, enabling only computations from CartesianState
+1. Compute the difference between other and self
+2. Compute the RIC DCM of self
+3. Rotate the difference into the RIC frame of self
+4. Strip the astrodynamical information from the frame, enabling only computations from CartesianState
:type other: Orbit
:rtype: Orbit
-
+
##### Method `right_ascension_deg` {#anise.astro.Orbit.right_ascension_deg}
> def right_ascension_deg(
@@ -1706,7 +3049,7 @@ Returns the right ascension of this orbit in degrees
:rtype: float
-
+
##### Method `rmag_km` {#anise.astro.Orbit.rmag_km}
> def rmag_km(
@@ -1718,7 +3061,7 @@ Returns the magnitude of the radius vector in km
:rtype: float
-
+
##### Method `rms_radius_km` {#anise.astro.Orbit.rms_radius_km}
> def rms_radius_km(
@@ -1732,7 +3075,7 @@ Returns the root sum squared (RMS) radius difference between this state and anot
:type other: Orbit
:rtype: float
-
+
##### Method `rms_velocity_km_s` {#anise.astro.Orbit.rms_velocity_km_s}
> def rms_velocity_km_s(
@@ -1746,7 +3089,7 @@ Returns the root sum squared (RMS) velocity difference between this state and an
:type other: Orbit
:rtype: float
-
+
##### Method `rss_radius_km` {#anise.astro.Orbit.rss_radius_km}
> def rss_radius_km(
@@ -1760,7 +3103,7 @@ Returns the root mean squared (RSS) radius difference between this state and ano
:type other: Orbit
:rtype: float
-
+
##### Method `rss_velocity_km_s` {#anise.astro.Orbit.rss_velocity_km_s}
> def rss_velocity_km_s(
@@ -1774,7 +3117,7 @@ Returns the root mean squared (RSS) velocity difference between this state and a
:type other: Orbit
:rtype: float
-
+
##### Method `semi_minor_axis_km` {#anise.astro.Orbit.semi_minor_axis_km}
> def semi_minor_axis_km(
@@ -1786,7 +3129,7 @@ Returns the semi minor axis in km, includes code for a hyperbolic orbit
:rtype: float
-
+
##### Method `semi_parameter_km` {#anise.astro.Orbit.semi_parameter_km}
> def semi_parameter_km(
@@ -1798,7 +3141,7 @@ Returns the semi parameter (or semilatus rectum)
:rtype: float
-
+
##### Method `set_aop_deg` {#anise.astro.Orbit.set_aop_deg}
> def set_aop_deg(
@@ -1812,7 +3155,7 @@ Mutates this orbit to change the AOP
:type new_aop_deg: float
:rtype: None
-
+
##### Method `set_ecc` {#anise.astro.Orbit.set_ecc}
> def set_ecc(
@@ -1826,7 +3169,7 @@ Mutates this orbit to change the ECC
:type new_ecc: float
:rtype: None
-
+
##### Method `set_inc_deg` {#anise.astro.Orbit.set_inc_deg}
> def set_inc_deg(
@@ -1840,7 +3183,7 @@ Mutates this orbit to change the INC
:type new_inc_deg: float
:rtype: None
-
+
##### Method `set_raan_deg` {#anise.astro.Orbit.set_raan_deg}
> def set_raan_deg(
@@ -1854,7 +3197,7 @@ Mutates this orbit to change the RAAN
:type new_raan_deg: float
:rtype: None
-
+
##### Method `set_sma_km` {#anise.astro.Orbit.set_sma_km}
> def set_sma_km(
@@ -1868,7 +3211,7 @@ Mutates this orbit to change the SMA
:type new_sma_km: float
:rtype: None
-
+
##### Method `set_ta_deg` {#anise.astro.Orbit.set_ta_deg}
> def set_ta_deg(
@@ -1882,7 +3225,7 @@ Mutates this orbit to change the TA
:type new_ta_deg: float
:rtype: None
-
+
##### Method `sma_altitude_km` {#anise.astro.Orbit.sma_altitude_km}
> def sma_altitude_km(
@@ -1894,7 +3237,19 @@ Returns the SMA altitude in km
:rtype: float
-
+
+##### Method `sma_brouwer_short_km` {#anise.astro.Orbit.sma_brouwer_short_km}
+
+> def sma_brouwer_short_km(
+> self,
+> /
+> )
+
+Returns the Brouwer-short mean semi-major axis in km.
+
+:rtype: float
+
+
##### Method `sma_km` {#anise.astro.Orbit.sma_km}
> def sma_km(
@@ -1906,7 +3261,7 @@ Returns the semi-major axis in km
:rtype: float
-
+
##### Method `ta_deg` {#anise.astro.Orbit.ta_deg}
> def ta_deg(
@@ -1925,7 +3280,7 @@ to determine whether the true anomaly should be 0.0 or 180.0. **In other words**
:rtype: float
-
+
##### Method `ta_dot_deg_s` {#anise.astro.Orbit.ta_dot_deg_s}
> def ta_dot_deg_s(
@@ -1937,7 +3292,7 @@ Returns the time derivative of the true anomaly computed as the 360.0 degrees di
:rtype: float
-
+
##### Method `tlong_deg` {#anise.astro.Orbit.tlong_deg}
> def tlong_deg(
@@ -1949,7 +3304,19 @@ Returns the true longitude in degrees
:rtype: float
-
+
+##### Method `to_asn1` {#anise.astro.Orbit.to_asn1}
+
+> def to_asn1(
+> self,
+> /
+> )
+
+Encodes this CartesianState (Orbit) into an ASN.1 DER encoded byte array.
+
+:rtype: bytes
+
+
##### Method `velocity_declination_deg` {#anise.astro.Orbit.velocity_declination_deg}
> def velocity_declination_deg(
@@ -1961,7 +3328,19 @@ Returns the velocity declination of this orbit in degrees
:rtype: float
-
+
+##### Method `velocity_km_s` {#anise.astro.Orbit.velocity_km_s}
+
+> def velocity_km_s(
+> self,
+> /
+> )
+
+velocity vector in km/s
+
+:rtype: np.array
+
+
##### Method `vinf_periapsis_km` {#anise.astro.Orbit.vinf_periapsis_km}
> def vinf_periapsis_km(
@@ -1976,7 +3355,7 @@ Returns an error if the orbit is not hyperbolic.
:type turn_angle_degrees: float
:rtype: float
-
+
##### Method `vinf_turn_angle_deg` {#anise.astro.Orbit.vinf_turn_angle_deg}
> def vinf_turn_angle_deg(
@@ -1991,7 +3370,7 @@ Returns an error if the orbit is not hyperbolic.
:type periapsis_km: float
:rtype: float
-
+
##### Method `vmag_km_s` {#anise.astro.Orbit.vmag_km_s}
> def vmag_km_s(
@@ -2003,7 +3382,7 @@ Returns the magnitude of the velocity vector in km/s
:rtype: float
-
+
##### Method `vnc_difference` {#anise.astro.Orbit.vnc_difference}
> def vnc_difference(
@@ -2016,16 +3395,15 @@ Returns a Cartesian state representing the VNC difference between self and other
Refer to dcm_from_vnc_to_inertial for details on the VNC frame.
##### Algorithm
-1. Compute the VNC DCM of self
-2. Rotate self into the VNC frame
-3. Rotation other into the VNC frame
-4. Compute the difference between these two states
-5. Strip the astrodynamical information from the frame, enabling only computations from CartesianState
+1. Compute the difference between other and self
+2. Compute the VNC DCM of self
+3. Rotate the difference into the VNC frame of self
+4. Strip the astrodynamical information from the frame, enabling only computations from CartesianState
:type other: Orbit
:rtype: Orbit
-
+
##### Method `with_aop_deg` {#anise.astro.Orbit.with_aop_deg}
> def with_aop_deg(
@@ -2039,7 +3417,7 @@ Returns a copy of the state with a new AOP
:type new_aop_deg: float
:rtype: Orbit
-
+
##### Method `with_apoapsis_periapsis_km` {#anise.astro.Orbit.with_apoapsis_periapsis_km}
> def with_apoapsis_periapsis_km(
@@ -2055,7 +3433,7 @@ Returns a copy of this state with the provided apoasis and periapsis
:type new_rp_km: float
:rtype: Orbit
-
+
##### Method `with_ecc` {#anise.astro.Orbit.with_ecc}
> def with_ecc(
@@ -2069,7 +3447,7 @@ Returns a copy of the state with a new ECC
:type new_ecc: float
:rtype: Orbit
-
+
##### Method `with_inc_deg` {#anise.astro.Orbit.with_inc_deg}
> def with_inc_deg(
@@ -2083,7 +3461,7 @@ Returns a copy of the state with a new INC
:type new_inc_deg: float
:rtype: Orbit
-
+
##### Method `with_raan_deg` {#anise.astro.Orbit.with_raan_deg}
> def with_raan_deg(
@@ -2097,7 +3475,7 @@ Returns a copy of the state with a new RAAN
:type new_raan_deg: float
:rtype: Orbit
-
+
##### Method `with_sma_km` {#anise.astro.Orbit.with_sma_km}
> def with_sma_km(
@@ -2111,7 +3489,7 @@ Returns a copy of the state with a new SMA
:type new_sma_km: float
:rtype: Orbit
-
+
##### Method `with_ta_deg` {#anise.astro.Orbit.with_ta_deg}
> def with_ta_deg(
@@ -2125,261 +3503,96 @@ Returns a copy of the state with a new TA
:type new_ta_deg: float
:rtype: Orbit
-
-# Module `anise.astro.constants` {#anise.astro.constants}
-
-
-## Classes
-
-### Class `CelestialObjects` {#anise.astro.constants.CelestialObjects}
+### Class `SRPData` {#anise.astro.SRPData}
-> class CelestialObjects(
-> ...
+> class SRPData(
+> area_m2,
+> coeff_reflectivity=None
> )
-
-#### Class variables
-
-
-##### Variable `EARTH` {#anise.astro.constants.CelestialObjects.EARTH}
-
-
-##### Variable `EARTH_MOON_BARYCENTER` {#anise.astro.constants.CelestialObjects.EARTH_MOON_BARYCENTER}
-
-
-##### Variable `JUPITER` {#anise.astro.constants.CelestialObjects.JUPITER}
-
-
-##### Variable `JUPITER_BARYCENTER` {#anise.astro.constants.CelestialObjects.JUPITER_BARYCENTER}
-
-
-##### Variable `MARS` {#anise.astro.constants.CelestialObjects.MARS}
-
-
-##### Variable `MARS_BARYCENTER` {#anise.astro.constants.CelestialObjects.MARS_BARYCENTER}
-
-
-##### Variable `MERCURY` {#anise.astro.constants.CelestialObjects.MERCURY}
-
-
-##### Variable `MOON` {#anise.astro.constants.CelestialObjects.MOON}
-
-##### Variable `NEPTUNE` {#anise.astro.constants.CelestialObjects.NEPTUNE}
+#### Instance variables
-
-##### Variable `NEPTUNE_BARYCENTER` {#anise.astro.constants.CelestialObjects.NEPTUNE_BARYCENTER}
-
-##### Variable `PLUTO_BARYCENTER` {#anise.astro.constants.CelestialObjects.PLUTO_BARYCENTER}
+##### Variable `area_m2` {#anise.astro.SRPData.area_m2}
-
-##### Variable `SATURN` {#anise.astro.constants.CelestialObjects.SATURN}
+Solar radiation pressure area in m^2 -- default 0.0
+:rtype: float
-
-##### Variable `SATURN_BARYCENTER` {#anise.astro.constants.CelestialObjects.SATURN_BARYCENTER}
-
-##### Variable `SOLAR_SYSTEM_BARYCENTER` {#anise.astro.constants.CelestialObjects.SOLAR_SYSTEM_BARYCENTER}
+##### Variable `coeff_reflectivity` {#anise.astro.SRPData.coeff_reflectivity}
-
-##### Variable `SUN` {#anise.astro.constants.CelestialObjects.SUN}
+Solar radiation pressure coefficient of reflectivity (C_r) -- default 1.8
+:rtype: float
-
-##### Variable `URANUS` {#anise.astro.constants.CelestialObjects.URANUS}
-
-##### Variable `URANUS_BARYCENTER` {#anise.astro.constants.CelestialObjects.URANUS_BARYCENTER}
+#### Methods
-
-##### Variable `VENUS` {#anise.astro.constants.CelestialObjects.VENUS}
-
-### Class `Frames` {#anise.astro.constants.Frames}
+##### Method `from_asn1` {#anise.astro.SRPData.from_asn1}
-> class Frames(
-> ...
+> def from_asn1(
+> data
> )
-
-#### Class variables
-
-
-##### Variable `EARTH_ECLIPJ2000` {#anise.astro.constants.Frames.EARTH_ECLIPJ2000}
-
-
-##### Variable `EARTH_ITRF93` {#anise.astro.constants.Frames.EARTH_ITRF93}
-
-
-##### Variable `EARTH_J2000` {#anise.astro.constants.Frames.EARTH_J2000}
-
-
-##### Variable `EARTH_MOON_BARYCENTER_J2000` {#anise.astro.constants.Frames.EARTH_MOON_BARYCENTER_J2000}
-
-
-##### Variable `EME2000` {#anise.astro.constants.Frames.EME2000}
-
-
-##### Variable `IAU_EARTH_FRAME` {#anise.astro.constants.Frames.IAU_EARTH_FRAME}
-
-
-##### Variable `IAU_JUPITER_FRAME` {#anise.astro.constants.Frames.IAU_JUPITER_FRAME}
-
-
-##### Variable `IAU_MARS_FRAME` {#anise.astro.constants.Frames.IAU_MARS_FRAME}
-
-
-##### Variable `IAU_MERCURY_FRAME` {#anise.astro.constants.Frames.IAU_MERCURY_FRAME}
-
-
-##### Variable `IAU_MOON_FRAME` {#anise.astro.constants.Frames.IAU_MOON_FRAME}
-
-
-##### Variable `IAU_NEPTUNE_FRAME` {#anise.astro.constants.Frames.IAU_NEPTUNE_FRAME}
+Decodes an ASN.1 DER encoded byte array into an SRPData object.
-
-##### Variable `IAU_SATURN_FRAME` {#anise.astro.constants.Frames.IAU_SATURN_FRAME}
+:type data: bytes
+:rtype: SRPData
-
-##### Variable `IAU_URANUS_FRAME` {#anise.astro.constants.Frames.IAU_URANUS_FRAME}
-
-##### Variable `IAU_VENUS_FRAME` {#anise.astro.constants.Frames.IAU_VENUS_FRAME}
+##### Method `to_asn1` {#anise.astro.SRPData.to_asn1}
-
-##### Variable `JUPITER_BARYCENTER_J2000` {#anise.astro.constants.Frames.JUPITER_BARYCENTER_J2000}
-
-
-##### Variable `MARS_BARYCENTER_J2000` {#anise.astro.constants.Frames.MARS_BARYCENTER_J2000}
-
-
-##### Variable `MERCURY_J2000` {#anise.astro.constants.Frames.MERCURY_J2000}
-
-
-##### Variable `MOON_J2000` {#anise.astro.constants.Frames.MOON_J2000}
-
-
-##### Variable `MOON_ME_DE421_FRAME` {#anise.astro.constants.Frames.MOON_ME_DE421_FRAME}
-
-
-##### Variable `MOON_ME_DE440_ME421_FRAME` {#anise.astro.constants.Frames.MOON_ME_DE440_ME421_FRAME}
-
-
-##### Variable `MOON_ME_FRAME` {#anise.astro.constants.Frames.MOON_ME_FRAME}
-
-
-##### Variable `MOON_PA_DE421_FRAME` {#anise.astro.constants.Frames.MOON_PA_DE421_FRAME}
-
-
-##### Variable `MOON_PA_DE440_FRAME` {#anise.astro.constants.Frames.MOON_PA_DE440_FRAME}
-
-
-##### Variable `MOON_PA_FRAME` {#anise.astro.constants.Frames.MOON_PA_FRAME}
-
-
-##### Variable `NEPTUNE_BARYCENTER_J2000` {#anise.astro.constants.Frames.NEPTUNE_BARYCENTER_J2000}
-
-
-##### Variable `PLUTO_BARYCENTER_J2000` {#anise.astro.constants.Frames.PLUTO_BARYCENTER_J2000}
-
-
-##### Variable `SATURN_BARYCENTER_J2000` {#anise.astro.constants.Frames.SATURN_BARYCENTER_J2000}
-
-
-##### Variable `SSB_J2000` {#anise.astro.constants.Frames.SSB_J2000}
-
-
-##### Variable `SUN_J2000` {#anise.astro.constants.Frames.SUN_J2000}
-
-
-##### Variable `URANUS_BARYCENTER_J2000` {#anise.astro.constants.Frames.URANUS_BARYCENTER_J2000}
-
-
-##### Variable `VENUS_J2000` {#anise.astro.constants.Frames.VENUS_J2000}
-
-
-### Class `Orientations` {#anise.astro.constants.Orientations}
-
-> class Orientations(
-> ...
+> def to_asn1(
+> self,
+> /
> )
-
-#### Class variables
-
-
-##### Variable `ECLIPJ2000` {#anise.astro.constants.Orientations.ECLIPJ2000}
+Encodes this SRPData object into an ASN.1 DER encoded byte array.
-
-##### Variable `IAU_EARTH` {#anise.astro.constants.Orientations.IAU_EARTH}
+:rtype: bytes
-
-##### Variable `IAU_JUPITER` {#anise.astro.constants.Orientations.IAU_JUPITER}
-
-##### Variable `IAU_MARS` {#anise.astro.constants.Orientations.IAU_MARS}
+### Class `TerrainMask` {#anise.astro.TerrainMask}
-
-##### Variable `IAU_MERCURY` {#anise.astro.constants.Orientations.IAU_MERCURY}
+> class TerrainMask(
+> azimuth_deg,
+> elevation_mask_deg
+> )
-
-##### Variable `IAU_MOON` {#anise.astro.constants.Orientations.IAU_MOON}
+TerrainMask is used to compute obstructions during AER calculations.
-
-##### Variable `IAU_NEPTUNE` {#anise.astro.constants.Orientations.IAU_NEPTUNE}
+:type azimuth_deg: float
+:type elevation_mask_deg: float
-
-##### Variable `IAU_SATURN` {#anise.astro.constants.Orientations.IAU_SATURN}
-
-##### Variable `IAU_URANUS` {#anise.astro.constants.Orientations.IAU_URANUS}
+#### Instance variables
-
-##### Variable `IAU_VENUS` {#anise.astro.constants.Orientations.IAU_VENUS}
-
-##### Variable `ITRF93` {#anise.astro.constants.Orientations.ITRF93}
+##### Variable `azimuth_deg` {#anise.astro.TerrainMask.azimuth_deg}
-
-##### Variable `J2000` {#anise.astro.constants.Orientations.J2000}
+:rtype: float
-
-##### Variable `MOON_ME` {#anise.astro.constants.Orientations.MOON_ME}
-
-##### Variable `MOON_ME_DE421` {#anise.astro.constants.Orientations.MOON_ME_DE421}
+##### Variable `elevation_mask_deg` {#anise.astro.TerrainMask.elevation_mask_deg}
-
-##### Variable `MOON_ME_DE440_ME421` {#anise.astro.constants.Orientations.MOON_ME_DE440_ME421}
+:rtype: float
-
-##### Variable `MOON_PA` {#anise.astro.constants.Orientations.MOON_PA}
-
-##### Variable `MOON_PA_DE421` {#anise.astro.constants.Orientations.MOON_PA_DE421}
+#### Methods
-
-##### Variable `MOON_PA_DE440` {#anise.astro.constants.Orientations.MOON_PA_DE440}
-
-### Class `UsualConstants` {#anise.astro.constants.UsualConstants}
+##### Method `from_flat_terrain` {#anise.astro.TerrainMask.from_flat_terrain}
-> class UsualConstants(
-> ...
+> def from_flat_terrain(
+> elevation_mask_deg
> )
-
-#### Class variables
-
-
-##### Variable `MEAN_EARTH_ANGULAR_VELOCITY_DEG_S` {#anise.astro.constants.UsualConstants.MEAN_EARTH_ANGULAR_VELOCITY_DEG_S}
-
-
-##### Variable `MEAN_MOON_ANGULAR_VELOCITY_DEG_S` {#anise.astro.constants.UsualConstants.MEAN_MOON_ANGULAR_VELOCITY_DEG_S}
+Creates a flat terrain mask with the provided elevation mask in degrees
-
-##### Variable `SPEED_OF_LIGHT_KM_S` {#anise.astro.constants.UsualConstants.SPEED_OF_LIGHT_KM_S}
+:type elevation_mask_deg: float
+:rtype: list
-----
Generated by *pdoc* 0.11.6 ().
diff --git a/docs/anise/reference/api/python/astro/constants.md b/docs/anise/reference/api/python/astro/constants.md
deleted file mode 100644
index 48beee5..0000000
--- a/docs/anise/reference/api/python/astro/constants.md
+++ /dev/null
@@ -1,233 +0,0 @@
-# Module `astro.constants`
-
-
-## Classes
-
-
-### Class `CelestialObjects`
-
-> class CelestialObjects(
-> ...
-> )
-
-
-#### Class variables
-
-
-##### Variable `EARTH`
-
-
-##### Variable `EARTH_MOON_BARYCENTER`
-
-
-##### Variable `JUPITER`
-
-
-##### Variable `JUPITER_BARYCENTER`
-
-
-##### Variable `MARS`
-
-
-##### Variable `MARS_BARYCENTER`
-
-
-##### Variable `MERCURY`
-
-
-##### Variable `MOON`
-
-
-##### Variable `NEPTUNE`
-
-
-##### Variable `NEPTUNE_BARYCENTER`
-
-
-##### Variable `PLUTO_BARYCENTER`
-
-
-##### Variable `SATURN`
-
-
-##### Variable `SATURN_BARYCENTER`
-
-
-##### Variable `SOLAR_SYSTEM_BARYCENTER`
-
-
-##### Variable `SUN`
-
-
-##### Variable `URANUS`
-
-
-##### Variable `URANUS_BARYCENTER`
-
-
-##### Variable `VENUS`
-
-
-### Class `Frames`
-
-> class Frames(
-> ...
-> )
-
-
-#### Class variables
-
-
-##### Variable `EARTH_ECLIPJ2000`
-
-
-##### Variable `EARTH_ITRF93`
-
-
-##### Variable `EARTH_J2000`
-
-
-##### Variable `EARTH_MOON_BARYCENTER_J2000`
-
-
-##### Variable `EME2000`
-
-
-##### Variable `IAU_EARTH_FRAME`
-
-
-##### Variable `IAU_JUPITER_FRAME`
-
-
-##### Variable `IAU_MARS_FRAME`
-
-
-##### Variable `IAU_MERCURY_FRAME`
-
-
-##### Variable `IAU_MOON_FRAME`
-
-
-##### Variable `IAU_NEPTUNE_FRAME`
-
-
-##### Variable `IAU_SATURN_FRAME`
-
-
-##### Variable `IAU_URANUS_FRAME`
-
-
-##### Variable `IAU_VENUS_FRAME`
-
-
-##### Variable `JUPITER_BARYCENTER_J2000`
-
-
-##### Variable `MARS_BARYCENTER_J2000`
-
-
-##### Variable `MERCURY_J2000`
-
-
-##### Variable `MOON_J2000`
-
-
-##### Variable `MOON_ME_FRAME`
-
-
-##### Variable `MOON_PA_FRAME`
-
-
-##### Variable `NEPTUNE_BARYCENTER_J2000`
-
-
-##### Variable `PLUTO_BARYCENTER_J2000`
-
-
-##### Variable `SATURN_BARYCENTER_J2000`
-
-
-##### Variable `SSB_J2000`
-
-
-##### Variable `SUN_J2000`
-
-
-##### Variable `URANUS_BARYCENTER_J2000`
-
-
-##### Variable `VENUS_J2000`
-
-
-### Class `Orientations`
-
-> class Orientations(
-> ...
-> )
-
-
-#### Class variables
-
-
-##### Variable `ECLIPJ2000`
-
-
-##### Variable `IAU_EARTH`
-
-
-##### Variable `IAU_JUPITER`
-
-
-##### Variable `IAU_MARS`
-
-
-##### Variable `IAU_MERCURY`
-
-
-##### Variable `IAU_MOON`
-
-
-##### Variable `IAU_NEPTUNE`
-
-
-##### Variable `IAU_SATURN`
-
-
-##### Variable `IAU_URANUS`
-
-
-##### Variable `IAU_VENUS`
-
-
-##### Variable `ITRF93`
-
-
-##### Variable `J2000`
-
-
-##### Variable `MOON_ME`
-
-
-##### Variable `MOON_PA`
-
-
-### Class `UsualConstants`
-
-> class UsualConstants(
-> ...
-> )
-
-
-#### Class variables
-
-
-##### Variable `MEAN_EARTH_ANGULAR_VELOCITY_DEG_S`
-
-
-##### Variable `MEAN_MOON_ANGULAR_VELOCITY_DEG_S`
-
-
-##### Variable `SPEED_OF_LIGHT_KM_S`
-
------
-Generated by *pdoc* 0.10.0 ().
diff --git a/docs/anise/reference/api/python/astro/index.md b/docs/anise/reference/api/python/astro/index.md
deleted file mode 100644
index 49722d0..0000000
--- a/docs/anise/reference/api/python/astro/index.md
+++ /dev/null
@@ -1,1261 +0,0 @@
-# Module `astro`
-
-
-## Classes
-
-
-### Class `AzElRange`
-
-> class AzElRange(
-> epoch,
-> azimuth_deg,
-> elevation_deg,
-> range_km,
-> range_rate_km_s
-> )
-
-A structure that stores the result of Azimuth, Elevation, Range, Range rate calculation.
-
-# Algorithm
-
-
-#### Instance variables
-
-
-##### Variable `azimuth_deg`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `elevation_deg`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `epoch`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `range_km`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `range_rate_km_s`
-
-Return an attribute of instance, which is of type owner.
-
-
-#### Methods
-
-
-##### Method `is_valid`
-
-> def is_valid(
-> self,
-> /
-> )
-
-Returns false if the range is less than one millimeter, or any of the angles are NaN.
-
-
-### Class `Ellipsoid`
-
-> class Ellipsoid(
-> semi_major_equatorial_radius_km,
-> polar_radius_km=None,
-> semi_minor_equatorial_radius_km=None
-> )
-
-Only the tri-axial Ellipsoid shape model is currently supported by ANISE.
-This is directly inspired from SPICE PCK.
-> For each body, three radii are listed: The first number is
-> the largest equatorial radius (the length of the semi-axis
-> containing the prime meridian), the second number is the smaller
-> equatorial radius, and the third is the polar radius.
-
-Example: Radii of the Earth.
-
- BODY399_RADII = ( 6378.1366 6378.1366 6356.7519 )
-
-
-#### Instance variables
-
-
-##### Variable `polar_radius_km`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `semi_major_equatorial_radius_km`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `semi_minor_equatorial_radius_km`
-
-Return an attribute of instance, which is of type owner.
-
-
-#### Methods
-
-
-##### Method `flattening`
-
-> def flattening(
-> self,
-> /
-> )
-
-Returns the flattening ratio, computed from the mean equatorial radius and the polar radius
-
-
-##### Method `is_sphere`
-
-> def is_sphere(
-> self,
-> /
-> )
-
-
-##### Method `is_spheroid`
-
-> def is_spheroid(
-> self,
-> /
-> )
-
-
-##### Method `mean_equatorial_radius_km`
-
-> def mean_equatorial_radius_km(
-> self,
-> /
-> )
-
-Returns the mean equatorial radius in kilometers
-
-
-### Class `Frame`
-
-> class Frame(
-> ephemeris_id,
-> orientation_id,
-> mu_km3_s2=None,
-> shape=None
-> )
-
-A Frame uniquely defined by its ephemeris center and orientation. Refer to FrameDetail for frames combined with parameters.
-
-
-#### Instance variables
-
-
-##### Variable `ephemeris_id`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `orientation_id`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `shape`
-
-Shape of the geoid of this frame, only defined on geodetic frames
-
-
-#### Methods
-
-
-##### Method `ephem_origin_id_match`
-
-> def ephem_origin_id_match(
-> self,
-> /,
-> other_id
-> )
-
-Returns true if the ephemeris origin is equal to the provided ID
-
-
-##### Method `ephem_origin_match`
-
-> def ephem_origin_match(
-> self,
-> /,
-> other
-> )
-
-Returns true if the ephemeris origin is equal to the provided frame
-
-
-##### Method `flattening`
-
-> def flattening(
-> self,
-> /
-> )
-
-Returns the flattening ratio (unitless)
-
-
-##### Method `is_celestial`
-
-> def is_celestial(
-> self,
-> /
-> )
-
-Returns whether this is a celestial frame
-
-
-##### Method `is_geodetic`
-
-> def is_geodetic(
-> self,
-> /
-> )
-
-Returns whether this is a geodetic frame
-
-
-##### Method `mean_equatorial_radius_km`
-
-> def mean_equatorial_radius_km(
-> self,
-> /
-> )
-
-Returns the mean equatorial radius in km, if defined
-
-
-##### Method `mu_km3_s2`
-
-> def mu_km3_s2(
-> self,
-> /
-> )
-
-Returns the gravitational parameters of this frame, if defined
-
-
-##### Method `orient_origin_id_match`
-
-> def orient_origin_id_match(
-> self,
-> /,
-> other_id
-> )
-
-Returns true if the orientation origin is equal to the provided ID
-
-
-##### Method `orient_origin_match`
-
-> def orient_origin_match(
-> self,
-> /,
-> other
-> )
-
-Returns true if the orientation origin is equal to the provided frame
-
-
-##### Method `polar_radius_km`
-
-> def polar_radius_km(
-> self,
-> /
-> )
-
-Returns the polar radius in km, if defined
-
-
-##### Method `semi_major_radius_km`
-
-> def semi_major_radius_km(
-> self,
-> /
-> )
-
-Returns the semi major radius of the tri-axial ellipoid shape of this frame, if defined
-
-
-##### Method `strip`
-
-> def strip(
-> self,
-> /
-> )
-
-Removes the graviational parameter and the shape information from this frame.
-Use this to prevent astrodynamical computations.
-
-
-##### Method `with_ephem`
-
-> def with_ephem(
-> self,
-> /,
-> new_ephem_id
-> )
-
-Returns a copy of this Frame whose ephemeris ID is set to the provided ID
-
-
-##### Method `with_mu_km3_s2`
-
-> def with_mu_km3_s2(
-> self,
-> /,
-> mu_km3_s2
-> )
-
-Returns a copy of this frame with the graviational parameter set to the new value.
-
-
-##### Method `with_orient`
-
-> def with_orient(
-> self,
-> /,
-> new_orient_id
-> )
-
-Returns a copy of this Frame whose orientation ID is set to the provided ID
-
-
-### Class `Orbit`
-
-> class Orbit(
-> x_km,
-> y_km,
-> z_km,
-> vx_km_s,
-> vy_km_s,
-> vz_km_s,
-> epoch,
-> frame
-> )
-
-Defines a Cartesian state in a given frame at a given epoch in a given time scale. Radius data is expressed in kilometers. Velocity data is expressed in kilometers per second.
-Regardless of the constructor used, this struct stores all the state information in Cartesian coordinates as these are always non singular.
-
-Unless noted otherwise, algorithms are from GMAT 2016a [StateConversionUtil.cpp](https://github.com/ChristopherRabotin/GMAT/blob/37201a6290e7f7b941bc98ee973a527a5857104b/src/base/util/StateConversionUtil.cpp).
-
-
-#### Instance variables
-
-
-##### Variable `epoch`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `frame`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `vx_km_s`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `vy_km_s`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `vz_km_s`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `x_km`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `y_km`
-
-Return an attribute of instance, which is of type owner.
-
-
-##### Variable `z_km`
-
-Return an attribute of instance, which is of type owner.
-
-
-#### Methods
-
-
-##### Method `add_aop_deg`
-
-> def add_aop_deg(
-> self,
-> /,
-> delta_aop_deg
-> )
-
-Returns a copy of the state with a provided AOP added to the current one
-
-
-##### Method `add_apoapsis_periapsis_km`
-
-> def add_apoapsis_periapsis_km(
-> self,
-> /,
-> delta_ra_km,
-> delta_rp_km
-> )
-
-Returns a copy of this state with the provided apoasis and periapsis added to the current values
-
-
-##### Method `add_ecc`
-
-> def add_ecc(
-> self,
-> /,
-> delta_ecc
-> )
-
-Returns a copy of the state with a provided ECC added to the current one
-
-
-##### Method `add_inc_deg`
-
-> def add_inc_deg(
-> self,
-> /,
-> delta_inc_deg
-> )
-
-Returns a copy of the state with a provided INC added to the current one
-
-
-##### Method `add_raan_deg`
-
-> def add_raan_deg(
-> self,
-> /,
-> delta_raan_deg
-> )
-
-Returns a copy of the state with a provided RAAN added to the current one
-
-
-##### Method `add_sma_km`
-
-> def add_sma_km(
-> self,
-> /,
-> delta_sma
-> )
-
-Returns a copy of the state with a provided SMA added to the current one
-
-
-##### Method `add_ta_deg`
-
-> def add_ta_deg(
-> self,
-> /,
-> delta_ta_deg
-> )
-
-Returns a copy of the state with a provided TA added to the current one
-
-
-##### Method `aol_deg`
-
-> def aol_deg(
-> self,
-> /
-> )
-
-Returns the argument of latitude in degrees
-
-NOTE: If the orbit is near circular, the AoL will be computed from the true longitude
-instead of relying on the ill-defined true anomaly.
-
-
-##### Method `aop_deg`
-
-> def aop_deg(
-> self,
-> /
-> )
-
-Returns the argument of periapsis in degrees
-
-
-##### Method `apoapsis_altitude_km`
-
-> def apoapsis_altitude_km(
-> self,
-> /
-> )
-
-Returns the altitude of apoapsis (or apogee around Earth), in kilometers.
-
-
-##### Method `apoapsis_km`
-
-> def apoapsis_km(
-> self,
-> /
-> )
-
-Returns the radius of apoapsis (or apogee around Earth), in kilometers.
-
-
-##### Method `at_epoch`
-
-> def at_epoch(
-> self,
-> /,
-> new_epoch
-> )
-
-Adjusts the true anomaly of this orbit using the mean anomaly.
-
-##### Astrodynamics note
-This is not a true propagation of the orbit. This is akin to a two body propagation ONLY without any other force models applied.
-Use Nyx for high fidelity propagation.
-
-
-##### Method `c3_km2_s2`
-
-> def c3_km2_s2(
-> self,
-> /
-> )
-
-Returns the $C_3$ of this orbit in km^2/s^2
-
-
-##### Method `declination_deg`
-
-> def declination_deg(
-> self,
-> /
-> )
-
-Returns the declination of this orbit in degrees
-
-
-##### Method `distance_to_km`
-
-> def distance_to_km(
-> self,
-> /,
-> other
-> )
-
-Returns the distance in kilometers between this state and another state, if both frame match (epoch does not need to match).
-
-
-##### Method `ea_deg`
-
-> def ea_deg(
-> self,
-> /
-> )
-
-Returns the eccentric anomaly in degrees
-
-This is a conversion from GMAT's StateConversionUtil::TrueToEccentricAnomaly
-
-
-##### Method `ecc`
-
-> def ecc(
-> self,
-> /
-> )
-
-Returns the eccentricity (no unit)
-
-
-##### Method `energy_km2_s2`
-
-> def energy_km2_s2(
-> self,
-> /
-> )
-
-Returns the specific mechanical energy in km^2/s^2
-
-
-##### Method `eq_within`
-
-> def eq_within(
-> self,
-> /,
-> other,
-> radial_tol_km,
-> velocity_tol_km_s
-> )
-
-Returns whether this orbit and another are equal within the specified radial and velocity absolute tolerances
-
-
-##### Method `fpa_deg`
-
-> def fpa_deg(
-> self,
-> /
-> )
-
-Returns the flight path angle in degrees
-
-
-##### Method `from_cartesian`
-
-> def from_cartesian(
-> x_km,
-> y_km,
-> z_km,
-> vx_km_s,
-> vy_km_s,
-> vz_km_s,
-> epoch,
-> frame
-> )
-
-Creates a new Cartesian state in the provided frame at the provided Epoch.
-
-**Units:** km, km, km, km/s, km/s, km/s
-
-
-##### Method `from_keplerian`
-
-> def from_keplerian(
-> sma,
-> ecc,
-> inc,
-> raan,
-> aop,
-> ta,
-> epoch,
-> frame
-> )
-
-Creates a new Orbit around the provided Celestial or Geoid frame from the Keplerian orbital elements.
-
-**Units:** km, none, degrees, degrees, degrees, degrees
-
-NOTE: The state is defined in Cartesian coordinates as they are non-singular. This causes rounding
-errors when creating a state from its Keplerian orbital elements (cf. the state tests).
-One should expect these errors to be on the order of 1e-12.
-
-
-##### Method `from_keplerian_altitude`
-
-> def from_keplerian_altitude(
-> sma_altitude,
-> ecc,
-> inc,
-> raan,
-> aop,
-> ta,
-> epoch,
-> frame
-> )
-
-Creates a new Orbit from the provided semi-major axis altitude in kilometers
-
-
-##### Method `from_keplerian_apsis_altitude`
-
-> def from_keplerian_apsis_altitude(
-> apo_alt,
-> peri_alt,
-> inc,
-> raan,
-> aop,
-> ta,
-> epoch,
-> frame
-> )
-
-Creates a new Orbit from the provided altitudes of apoapsis and periapsis, in kilometers
-
-
-##### Method `from_keplerian_apsis_radii`
-
-> def from_keplerian_apsis_radii(
-> r_a,
-> r_p,
-> inc,
-> raan,
-> aop,
-> ta,
-> epoch,
-> frame
-> )
-
-Attempts to create a new Orbit from the provided radii of apoapsis and periapsis, in kilometers
-
-
-##### Method `from_keplerian_mean_anomaly`
-
-> def from_keplerian_mean_anomaly(
-> sma_km,
-> ecc,
-> inc_deg,
-> raan_deg,
-> aop_deg,
-> ma_deg,
-> epoch,
-> frame
-> )
-
-Initializes a new orbit from the Keplerian orbital elements using the mean anomaly instead of the true anomaly.
-
-##### Implementation notes
-This function starts by converting the mean anomaly to true anomaly, and then it initializes the orbit
-using the keplerian(..) method.
-The conversion is from GMAT's MeanToTrueAnomaly function, transliterated originally by Claude and GPT4 with human adjustments.
-
-
-##### Method `from_latlongalt`
-
-> def from_latlongalt(
-> latitude_deg,
-> longitude_deg,
-> height_km,
-> angular_velocity,
-> epoch,
-> frame
-> )
-
-Creates a new Orbit from the latitude (φ), longitude (λ) and height (in km) with respect to the frame's ellipsoid given the angular velocity.
-
-**Units:** degrees, degrees, km, rad/s
-NOTE: This computation differs from the spherical coordinates because we consider the flattening of body.
-Reference: G. Xu and Y. Xu, "GPS", DOI 10.1007/978-3-662-50367-6_2, 2016
-
-
-##### Method `height_km`
-
-> def height_km(
-> self,
-> /
-> )
-
-Returns the geodetic height in km.
-
-Reference: Vallado, 4th Ed., Algorithm 12 page 172.
-
-
-##### Method `hmag`
-
-> def hmag(
-> self,
-> /
-> )
-
-Returns the norm of the orbital momentum
-
-
-##### Method `hx`
-
-> def hx(
-> self,
-> /
-> )
-
-Returns the orbital momentum value on the X axis
-
-
-##### Method `hy`
-
-> def hy(
-> self,
-> /
-> )
-
-Returns the orbital momentum value on the Y axis
-
-
-##### Method `hyperbolic_anomaly_deg`
-
-> def hyperbolic_anomaly_deg(
-> self,
-> /
-> )
-
-Returns the hyperbolic anomaly in degrees between 0 and 360.0
-Returns an error if the orbit is not hyperbolic.
-
-
-##### Method `hz`
-
-> def hz(
-> self,
-> /
-> )
-
-Returns the orbital momentum value on the Z axis
-
-
-##### Method `inc_deg`
-
-> def inc_deg(
-> self,
-> /
-> )
-
-Returns the inclination in degrees
-
-
-##### Method `is_brouwer_short_valid`
-
-> def is_brouwer_short_valid(
-> self,
-> /
-> )
-
-Returns whether this state satisfies the requirement to compute the Mean Brouwer Short orbital
-element set.
-
-This is a conversion from GMAT's StateConversionUtil::CartesianToBrouwerMeanShort.
-The details are at the log level info.
-NOTE: Mean Brouwer Short are only defined around Earth. However, nyx does *not* check the
-main celestial body around which the state is defined (GMAT does perform this verification).
-
-
-##### Method `latitude_deg`
-
-> def latitude_deg(
-> self,
-> /
-> )
-
-Returns the geodetic latitude (φ) in degrees. Value is between -180 and +180 degrees.
-
-##### Frame warning
-This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this function, or the computation is **invalid**.
-
-
-##### Method `latlongalt`
-
-> def latlongalt(
-> self,
-> /
-> )
-
-Returns the geodetic latitude, geodetic longitude, and geodetic height, respectively in degrees, degrees, and kilometers.
-
-##### Algorithm
-This uses the Heikkinen procedure, which is not iterative. The results match Vallado and GMAT.
-
-
-##### Method `light_time`
-
-> def light_time(
-> self,
-> /
-> )
-
-Returns the light time duration between this object and the origin of its reference frame.
-
-
-##### Method `longitude_deg`
-
-> def longitude_deg(
-> self,
-> /
-> )
-
-Returns the geodetic longitude (λ) in degrees. Value is between 0 and 360 degrees.
-
-##### Frame warning
-This state MUST be in the body fixed frame (e.g. ITRF93) prior to calling this function, or the computation is **invalid**.
-
-
-##### Method `ma_deg`
-
-> def ma_deg(
-> self,
-> /
-> )
-
-Returns the mean anomaly in degrees
-
-This is a conversion from GMAT's StateConversionUtil::TrueToMeanAnomaly
-
-
-##### Method `periapsis_altitude_km`
-
-> def periapsis_altitude_km(
-> self,
-> /
-> )
-
-Returns the altitude of periapsis (or perigee around Earth), in kilometers.
-
-
-##### Method `periapsis_km`
-
-> def periapsis_km(
-> self,
-> /
-> )
-
-Returns the radius of periapsis (or perigee around Earth), in kilometers.
-
-
-##### Method `period`
-
-> def period(
-> self,
-> /
-> )
-
-Returns the period in seconds
-
-
-##### Method `raan_deg`
-
-> def raan_deg(
-> self,
-> /
-> )
-
-Returns the right ascension of the ascending node in degrees
-
-
-##### Method `ric_difference`
-
-> def ric_difference(
-> self,
-> /,
-> other
-> )
-
-Returns a Cartesian state representing the RIC difference between self and other, in position and velocity (with transport theorem).
-Refer to dcm_from_ric_to_inertial for details on the RIC frame.
-
-##### Algorithm
-1. Compute the RIC DCM of self
-2. Rotate self into the RIC frame
-3. Rotation other into the RIC frame
-4. Compute the difference between these two states
-5. Strip the astrodynamical information from the frame, enabling only computations from CartesianState
-
-
-##### Method `right_ascension_deg`
-
-> def right_ascension_deg(
-> self,
-> /
-> )
-
-Returns the right ascension of this orbit in degrees
-
-
-##### Method `rmag_km`
-
-> def rmag_km(
-> self,
-> /
-> )
-
-Returns the magnitude of the radius vector in km
-
-
-##### Method `rss_radius_km`
-
-> def rss_radius_km(
-> self,
-> /,
-> other
-> )
-
-Returns the root mean squared (RSS) radius difference between this state and another state, if both frames match (epoch does not need to match)
-
-
-##### Method `rss_velocity_km_s`
-
-> def rss_velocity_km_s(
-> self,
-> /,
-> other
-> )
-
-Returns the root mean squared (RSS) velocity difference between this state and another state, if both frames match (epoch does not need to match)
-
-
-##### Method `semi_minor_axis_km`
-
-> def semi_minor_axis_km(
-> self,
-> /
-> )
-
-Returns the semi minor axis in km, includes code for a hyperbolic orbit
-
-
-##### Method `semi_parameter_km`
-
-> def semi_parameter_km(
-> self,
-> /
-> )
-
-Returns the semi parameter (or semilatus rectum)
-
-
-##### Method `set_aop_deg`
-
-> def set_aop_deg(
-> self,
-> /,
-> new_aop_deg
-> )
-
-Mutates this orbit to change the AOP
-
-
-##### Method `set_ecc`
-
-> def set_ecc(
-> self,
-> /,
-> new_ecc
-> )
-
-Mutates this orbit to change the ECC
-
-
-##### Method `set_inc_deg`
-
-> def set_inc_deg(
-> self,
-> /,
-> new_inc_deg
-> )
-
-Mutates this orbit to change the INC
-
-
-##### Method `set_raan_deg`
-
-> def set_raan_deg(
-> self,
-> /,
-> new_raan_deg
-> )
-
-Mutates this orbit to change the RAAN
-
-
-##### Method `set_sma_km`
-
-> def set_sma_km(
-> self,
-> /,
-> new_sma_km
-> )
-
-Mutates this orbit to change the SMA
-
-
-##### Method `set_ta_deg`
-
-> def set_ta_deg(
-> self,
-> /,
-> new_ta_deg
-> )
-
-Mutates this orbit to change the TA
-
-
-##### Method `sma_altitude_km`
-
-> def sma_altitude_km(
-> self,
-> /
-> )
-
-Returns the SMA altitude in km
-
-
-##### Method `sma_km`
-
-> def sma_km(
-> self,
-> /
-> )
-
-Returns the semi-major axis in km
-
-
-##### Method `ta_deg`
-
-> def ta_deg(
-> self,
-> /
-> )
-
-Returns the true anomaly in degrees between 0 and 360.0
-
-NOTE: This function will emit a warning stating that the TA should be avoided if in a very near circular orbit
-Code from
-
-LIMITATION: For an orbit whose true anomaly is (very nearly) 0.0 or 180.0, this function may return either 0.0 or 180.0 with a very small time increment.
-This is due to the precision of the cosine calculation: if the arccosine calculation is out of bounds, the sign of the cosine of the true anomaly is used
-to determine whether the true anomaly should be 0.0 or 180.0. **In other words**, there is an ambiguity in the computation in the true anomaly exactly at 180.0 and 0.0.
-
-
-##### Method `ta_dot_deg_s`
-
-> def ta_dot_deg_s(
-> self,
-> /
-> )
-
-Returns the time derivative of the true anomaly computed as the 360.0 degrees divided by the orbital period (in seconds).
-
-
-##### Method `tlong_deg`
-
-> def tlong_deg(
-> self,
-> /
-> )
-
-Returns the true longitude in degrees
-
-
-##### Method `velocity_declination_deg`
-
-> def velocity_declination_deg(
-> self,
-> /
-> )
-
-Returns the velocity declination of this orbit in degrees
-
-
-##### Method `vinf_periapsis_km`
-
-> def vinf_periapsis_km(
-> self,
-> /,
-> turn_angle_degrees
-> )
-
-Returns the radius of periapse in kilometers for the provided turn angle of this hyperbolic orbit.
-Returns an error if the orbit is not hyperbolic.
-
-
-##### Method `vinf_turn_angle_deg`
-
-> def vinf_turn_angle_deg(
-> self,
-> /,
-> periapsis_km
-> )
-
-Returns the turn angle in degrees for the provided radius of periapse passage of this hyperbolic orbit
-Returns an error if the orbit is not hyperbolic.
-
-
-##### Method `vmag_km_s`
-
-> def vmag_km_s(
-> self,
-> /
-> )
-
-Returns the magnitude of the velocity vector in km/s
-
-
-##### Method `with_aop_deg`
-
-> def with_aop_deg(
-> self,
-> /,
-> new_aop_deg
-> )
-
-Returns a copy of the state with a new AOP
-
-
-##### Method `with_apoapsis_periapsis_km`
-
-> def with_apoapsis_periapsis_km(
-> self,
-> /,
-> new_ra_km,
-> new_rp_km
-> )
-
-Returns a copy of this state with the provided apoasis and periapsis
-
-
-##### Method `with_ecc`
-
-> def with_ecc(
-> self,
-> /,
-> new_ecc
-> )
-
-Returns a copy of the state with a new ECC
-
-
-##### Method `with_inc_deg`
-
-> def with_inc_deg(
-> self,
-> /,
-> new_inc_deg
-> )
-
-Returns a copy of the state with a new INC
-
-
-##### Method `with_raan_deg`
-
-> def with_raan_deg(
-> self,
-> /,
-> new_raan_deg
-> )
-
-Returns a copy of the state with a new RAAN
-
-
-##### Method `with_sma_km`
-
-> def with_sma_km(
-> self,
-> /,
-> new_sma_km
-> )
-
-Returns a copy of the state with a new SMA
-
-
-##### Method `with_ta_deg`
-
-> def with_ta_deg(
-> self,
-> /,
-> new_ta_deg
-> )
-
-Returns a copy of the state with a new TA
-
------
-Generated by *pdoc* 0.10.0 ().
diff --git a/docs/anise/reference/api/python/constants.md b/docs/anise/reference/api/python/constants.md
index 67db056..2da0503 100644
--- a/docs/anise/reference/api/python/constants.md
+++ b/docs/anise/reference/api/python/constants.md
@@ -1,3 +1,18 @@
+---
+description: |
+ API documentation for modules: anise.constants.
+
+lang: en
+
+classoption: oneside
+geometry: margin=1in
+papersize: a4
+
+linkcolor: blue
+links-as-notes: true
+...
+
+
# Module `anise.constants` {#anise.constants}
@@ -6,9 +21,7 @@
### Class `CelestialObjects` {#anise.constants.CelestialObjects}
-> class CelestialObjects(
-> ...
-> )
+> class CelestialObjects
#### Class variables
@@ -70,9 +83,7 @@
### Class `Frames` {#anise.constants.Frames}
-> class Frames(
-> ...
-> )
+> class Frames
#### Class variables
@@ -87,12 +98,33 @@
##### Variable `EARTH_J2000` {#anise.constants.Frames.EARTH_J2000}
+##### Variable `EARTH_MOD_FRAME` {#anise.constants.Frames.EARTH_MOD_FRAME}
+
+
+##### Variable `EARTH_MOD_LEGACY_FRAME` {#anise.constants.Frames.EARTH_MOD_LEGACY_FRAME}
+
+
##### Variable `EARTH_MOON_BARYCENTER_J2000` {#anise.constants.Frames.EARTH_MOON_BARYCENTER_J2000}
+##### Variable `EARTH_TEME_FRAME` {#anise.constants.Frames.EARTH_TEME_FRAME}
+
+
+##### Variable `EARTH_TEME_LEGACY_FRAME` {#anise.constants.Frames.EARTH_TEME_LEGACY_FRAME}
+
+
+##### Variable `EARTH_TOD_FRAME` {#anise.constants.Frames.EARTH_TOD_FRAME}
+
+
+##### Variable `EARTH_TOD_LEGACY_FRAME` {#anise.constants.Frames.EARTH_TOD_LEGACY_FRAME}
+
+
##### Variable `EME2000` {#anise.constants.Frames.EME2000}
+##### Variable `GCRF` {#anise.constants.Frames.GCRF}
+
+
##### Variable `IAU_EARTH_FRAME` {#anise.constants.Frames.IAU_EARTH_FRAME}
@@ -120,12 +152,24 @@
##### Variable `IAU_VENUS_FRAME` {#anise.constants.Frames.IAU_VENUS_FRAME}
+##### Variable `ICRF` {#anise.constants.Frames.ICRF}
+
+
##### Variable `JUPITER_BARYCENTER_J2000` {#anise.constants.Frames.JUPITER_BARYCENTER_J2000}
+##### Variable `JUPITER_INERTIAL_FRAME` {#anise.constants.Frames.JUPITER_INERTIAL_FRAME}
+
+
##### Variable `MARS_BARYCENTER_J2000` {#anise.constants.Frames.MARS_BARYCENTER_J2000}
+##### Variable `MARS_INERTIAL_FRAME` {#anise.constants.Frames.MARS_INERTIAL_FRAME}
+
+
+##### Variable `MERCURY_INERTIAL_FRAME` {#anise.constants.Frames.MERCURY_INERTIAL_FRAME}
+
+
##### Variable `MERCURY_J2000` {#anise.constants.Frames.MERCURY_J2000}
@@ -141,6 +185,9 @@
##### Variable `MOON_ME_FRAME` {#anise.constants.Frames.MOON_ME_FRAME}
+##### Variable `MOON_MOD_FRAME` {#anise.constants.Frames.MOON_MOD_FRAME}
+
+
##### Variable `MOON_PA_DE421_FRAME` {#anise.constants.Frames.MOON_PA_DE421_FRAME}
@@ -150,15 +197,24 @@
##### Variable `MOON_PA_FRAME` {#anise.constants.Frames.MOON_PA_FRAME}
+##### Variable `MOON_TOD_FRAME` {#anise.constants.Frames.MOON_TOD_FRAME}
+
+
##### Variable `NEPTUNE_BARYCENTER_J2000` {#anise.constants.Frames.NEPTUNE_BARYCENTER_J2000}
+##### Variable `NEPTUNE_INERTIAL_FRAME` {#anise.constants.Frames.NEPTUNE_INERTIAL_FRAME}
+
+
##### Variable `PLUTO_BARYCENTER_J2000` {#anise.constants.Frames.PLUTO_BARYCENTER_J2000}
##### Variable `SATURN_BARYCENTER_J2000` {#anise.constants.Frames.SATURN_BARYCENTER_J2000}
+##### Variable `SATURN_INERTIAL_FRAME` {#anise.constants.Frames.SATURN_INERTIAL_FRAME}
+
+
##### Variable `SSB_J2000` {#anise.constants.Frames.SSB_J2000}
@@ -168,19 +224,50 @@
##### Variable `URANUS_BARYCENTER_J2000` {#anise.constants.Frames.URANUS_BARYCENTER_J2000}
+##### Variable `URANUS_INERTIAL_FRAME` {#anise.constants.Frames.URANUS_INERTIAL_FRAME}
+
+
+##### Variable `VENUS_INERTIAL_FRAME` {#anise.constants.Frames.VENUS_INERTIAL_FRAME}
+
+
##### Variable `VENUS_J2000` {#anise.constants.Frames.VENUS_J2000}
### Class `Orientations` {#anise.constants.Orientations}
-> class Orientations(
-> ...
-> )
+> class Orientations
#### Class variables
+##### Variable `EARTH_MOD` {#anise.constants.Orientations.EARTH_MOD}
+
+
+##### Variable `EARTH_MOD_1976` {#anise.constants.Orientations.EARTH_MOD_1976}
+
+
+##### Variable `EARTH_MOD_2000` {#anise.constants.Orientations.EARTH_MOD_2000}
+
+
+##### Variable `EARTH_TEME` {#anise.constants.Orientations.EARTH_TEME}
+
+
+##### Variable `EARTH_TEME_LEGACY` {#anise.constants.Orientations.EARTH_TEME_LEGACY}
+
+
+##### Variable `EARTH_TOD` {#anise.constants.Orientations.EARTH_TOD}
+
+
+##### Variable `EARTH_TOD_1980` {#anise.constants.Orientations.EARTH_TOD_1980}
+
+
+##### Variable `EARTH_TOD_2000A` {#anise.constants.Orientations.EARTH_TOD_2000A}
+
+
+##### Variable `EARTH_TOD_2000B` {#anise.constants.Orientations.EARTH_TOD_2000B}
+
+
##### Variable `ECLIPJ2000` {#anise.constants.Orientations.ECLIPJ2000}
@@ -211,6 +298,9 @@
##### Variable `IAU_VENUS` {#anise.constants.Orientations.IAU_VENUS}
+##### Variable `ICRS` {#anise.constants.Orientations.ICRS}
+
+
##### Variable `ITRF93` {#anise.constants.Orientations.ITRF93}
@@ -226,6 +316,9 @@
##### Variable `MOON_ME_DE440_ME421` {#anise.constants.Orientations.MOON_ME_DE440_ME421}
+##### Variable `MOON_MOD` {#anise.constants.Orientations.MOON_MOD}
+
+
##### Variable `MOON_PA` {#anise.constants.Orientations.MOON_PA}
@@ -235,11 +328,12 @@
##### Variable `MOON_PA_DE440` {#anise.constants.Orientations.MOON_PA_DE440}
+##### Variable `MOON_TOD` {#anise.constants.Orientations.MOON_TOD}
+
+
### Class `UsualConstants` {#anise.constants.UsualConstants}
-> class UsualConstants(
-> ...
-> )
+> class UsualConstants
#### Class variables
diff --git a/docs/anise/reference/api/python/rotation.md b/docs/anise/reference/api/python/rotation.md
index 30897ed..1bb713a 100644
--- a/docs/anise/reference/api/python/rotation.md
+++ b/docs/anise/reference/api/python/rotation.md
@@ -1,3 +1,18 @@
+---
+description: |
+ API documentation for modules: anise.rotation.
+
+lang: en
+
+classoption: oneside
+geometry: margin=1in
+papersize: a4
+
+linkcolor: blue
+links-as-notes: true
+...
+
+
# Module `anise.rotation` {#anise.rotation}
@@ -33,12 +48,14 @@ It provides a number of run-time checks that prevent invalid rotations.
##### Variable `rot_mat` {#anise.rotation.DCM.rot_mat}
-:rtype: numpy.array
+Return the position DCM (3x3 matrix)
+:rtype: numpy.ndarray
##### Variable `rot_mat_dt` {#anise.rotation.DCM.rot_mat_dt}
-:rtype: numpy.array
+Return the time derivative of this DMC, if set.
+:rtype: numpy.ndarray
##### Variable `to_id` {#anise.rotation.DCM.to_id}
@@ -49,6 +66,64 @@ It provides a number of run-time checks that prevent invalid rotations.
#### Methods
+##### Method `angular_velocity_deg_s` {#anise.rotation.DCM.angular_velocity_deg_s}
+
+> def angular_velocity_deg_s(
+> self,
+> /
+> )
+
+Returns the angular velocity vector in deg/s if a rotation rate is defined.
+:rtype: np.array
+
+
+##### Method `angular_velocity_rad_s` {#anise.rotation.DCM.angular_velocity_rad_s}
+
+> def angular_velocity_rad_s(
+> self,
+> /
+> )
+
+Returns the angular velocity vector in rad/s of this DCM is it has a defined rotation rate.
+:rtype: np.array
+
+
+##### Method `from_align_and_clock` {#anise.rotation.DCM.from_align_and_clock}
+
+> def from_align_and_clock(
+> primary_body_axis,
+> primary_inertial_vec,
+> secondary_body_axis,
+> secondary_inertial_vec,
+> from_id,
+> to_id
+> )
+
+Constructs a DCM using the "Align and Clock" (Two-Vector Targeting / TRIAD) method.
+
+This defines a rotation based on two geometric constraints:
+1. **Align**: The primary\_body\_axis is aligned exactly with the primary\_inertial\_vec.
+2. **Clock**: The secondary\_body\_axis is aligned as closely as possible with the secondary\_inertial\_vec.
+
+This constructs the rotation matrix $R_{from \to to}$.
+
+##### Arguments
+* primary\_body\_axis - The axis in the "from" frame to align (e.g. Sensor Boresight).
+* primary\_inertial\_vec - The target vector in the "to" frame (e.g. Vector to Earth).
+* secondary\_body\_axis - The axis in the "from" frame to clock (e.g. Solar Panel Normal).
+* secondary\_inertial\_vec - The target vector in the "to" frame (e.g. Vector to Sun).
+* from - The ID of the source frame.
+* to - The ID of the destination frame.
+
+:type primary_body_axis: np.array
+:type primary_inertial_vec: np.array
+:type secondary_body_axis: np.array
+:type secondary_inertial_vec: np.array
+:type from_id: int
+:type to_id: int
+:rtype: DCM
+
+
##### Method `from_identity` {#anise.rotation.DCM.from_identity}
> def from_identity(
@@ -126,7 +201,7 @@ Source: euler3 function from Basilisk
Returns the 6x6 DCM to rotate a state. If the time derivative of this DCM is defined, this 6x6 accounts for the transport theorem.
Warning: you MUST manually install numpy to call this function.
-:rtype: numpy.array
+:rtype: numpy.ndarray
##### Method `is_identity` {#anise.rotation.DCM.is_identity}
@@ -161,6 +236,27 @@ The criteria for validity are:
:rtype: bool
+##### Method `skew_symmetric` {#anise.rotation.DCM.skew_symmetric}
+
+> def skew_symmetric(
+> self,
+> /
+> )
+
+Returns the skew symmetric matrix if this DCM defines a rotation rate.
+:rtype: np.array
+
+
+##### Method `to_quaternion` {#anise.rotation.DCM.to_quaternion}
+
+> def to_quaternion(
+> self,
+> /
+> )
+
+:rtype: Quaternion
+
+
##### Method `transpose` {#anise.rotation.DCM.transpose}
> def transpose(
@@ -172,5 +268,292 @@ Returns the transpose of this DCM
:rtype: DCM
+
+### Class `Quaternion` {#anise.rotation.Quaternion}
+
+> class Quaternion(
+> w,
+> x,
+> y,
+> z,
+> from_id,
+> to_id
+> )
+
+Represents the orientation of a rigid body or a coordinate frame transformation in three-dimensional space using Euler parameters.
+
+Euler parameters, also known as unit quaternions, are a set of four parameters w, x, y, z.
+They are particularly useful because they avoid gimbal lock, are more compact than rotation matrices,
+and allow for smooth interpolation (SLERP).
+
+### Conventions
+
+ANISE strictly adheres to the following conventions to ensure consistency with [DCM](#anise.rotation.DCM "anise.rotation.DCM") and standard
+Guidance, Navigation, and Control (GNC) mathematics:
+
+1. **Hamiltonian Algebra:** The quaternion multiplication follows the right-handed rule where \
+ `i * j = k`. This is the standard in robotics and computer graphics, but distinct from the
+ "JPL/Shuster" convention (`i * j = -k`) sometimes found in legacy aerospace software.
+
+2. **Passive Rotation (Coordinate Transformation):** A quaternion defined with `from: A` and `to: B`
+ represents the transformation of **coordinates** from Frame A to Frame B.
+ * The rotation of a vector v is computed as: `v_B = q.conjugate() * v_A * q`.
+ * This matches the behavior of a Direction Cosine Matrix (DCM): `v_B = [DCM_A->B] * v_A`.
+
+3. **Operator Composition (Backward Chaining):** Rotations are composed in "Operator Order",
+ matching matrix multiplication rules.
+ * To compute the rotation A -> C, you multiply B->C by A->B.
+ * `q_A_to_C = q_B_to_C * q_A_to_B`
+ * ANISE enforces strict frame checking: LHS.from must equal RHS.to.
+
+### Definitions
+
+Euler parameters are defined in terms of the principal rotation vector. If a frame is rotated
+by an angle θ about a unit axis `e = [e1, e2, e3]`:
+
+* `w = cos(θ / 2)`
+* `x = e1 * sin(θ / 2)`
+* `y = e2 * sin(θ / 2)`
+* `z = e3 * sin(θ / 2)`
+
+These parameters satisfy `w^2 + x^2 + y^2 + z^2 = 1`, which means they represent
+a rotation in SO(3) and can be used to interpolate rotations smoothly.
+
+### Applications
+
+In the context of spacecraft mechanics, Euler parameters are often used because they provide a
+numerically stable way to represent the attitude of a spacecraft without the singularities that
+are present with Euler angles.
+
+### Usage
+Importantly, ANISE prevents the composition of two Euler Parameters if the frames do not match.
+
+:type w: float
+:type x: float
+:type y: float
+:type z: float
+:type from_id: int
+:type to_id: int
+
+
+#### Instance variables
+
+
+##### Variable `from_id` {#anise.rotation.Quaternion.from_id}
+
+:rtype: int
+
+
+##### Variable `to_id` {#anise.rotation.Quaternion.to_id}
+
+:rtype: int
+
+
+##### Variable `w` {#anise.rotation.Quaternion.w}
+
+:rtype: float
+
+
+##### Variable `x` {#anise.rotation.Quaternion.x}
+
+:rtype: float
+
+
+##### Variable `y` {#anise.rotation.Quaternion.y}
+
+:rtype: float
+
+
+##### Variable `z` {#anise.rotation.Quaternion.z}
+
+:rtype: float
+
+
+#### Methods
+
+
+##### Method `about_x` {#anise.rotation.Quaternion.about_x}
+
+> def about_x(
+> angle_rad,
+> from_id,
+> to_id
+> )
+
+Creates an Euler Parameter representing the short way rotation about the X (R1) axis
+
+:type angle_rad: float
+:type from_id: int
+:type to_id: int
+:rtype: Quaternion
+
+
+##### Method `about_y` {#anise.rotation.Quaternion.about_y}
+
+> def about_y(
+> angle_rad,
+> from_id,
+> to_id
+> )
+
+Creates an Euler Parameter representing the short way rotation about the Y (R2) axis
+
+:type angle_rad: float
+:type from_id: int
+:type to_id: int
+:rtype: Quaternion
+
+
+##### Method `about_z` {#anise.rotation.Quaternion.about_z}
+
+> def about_z(
+> angle_rad,
+> from_id,
+> to_id
+> )
+
+Creates an Euler Parameter representing the short way rotation about the Z (R3) axis
+
+:type angle_rad: float
+:type from_id: int
+:type to_id: int
+:rtype: Quaternion
+
+
+##### Method `as_vector` {#anise.rotation.Quaternion.as_vector}
+
+> def as_vector(
+> self,
+> /
+> )
+
+Returns the data of this EP as a vector.
+:rtype: np.array
+
+
+##### Method `b_matrix` {#anise.rotation.Quaternion.b_matrix}
+
+> def b_matrix(
+> self,
+> /
+> )
+
+Returns the 4x3 matrix which relates the body angular velocity vector w to the derivative of this Euler Parameter.
+dQ/dt = 1/2 [B(Q)] w
+
+:rtype: np.array
+
+
+##### Method `conjugate` {#anise.rotation.Quaternion.conjugate}
+
+> def conjugate(
+> self,
+> /
+> )
+
+Compute the conjugate of the quaternion.
+
+##### Note
+Because Euler Parameters are unit quaternions, the inverse and the conjugate are identical.
+
+:rtype: Quaternion
+
+
+##### Method `derivative` {#anise.rotation.Quaternion.derivative}
+
+> def derivative(
+> self,
+> /,
+> omega_rad_s
+> )
+
+Returns the euler parameter derivative for this EP and the body angular velocity vector w
+dQ/dt = 1/2 [B(Q)] omega_rad_s
+
+:type omega_rad_s: np.array
+:rtype: Quaternion
+
+
+##### Method `is_zero` {#anise.rotation.Quaternion.is_zero}
+
+> def is_zero(
+> self,
+> /
+> )
+
+Returns true if the quaternion represents a rotation of zero radians
+
+:rtype: bool
+
+
+##### Method `normalize` {#anise.rotation.Quaternion.normalize}
+
+> def normalize(
+> self,
+> /
+> )
+
+Normalize the quaternion.
+
+:rtype: Quaternion
+
+
+##### Method `prv` {#anise.rotation.Quaternion.prv}
+
+> def prv(
+> self,
+> /
+> )
+
+Returns the principal rotation vector representation of this Euler Parameter
+:rtype: np.array
+
+
+##### Method `scalar_norm` {#anise.rotation.Quaternion.scalar_norm}
+
+> def scalar_norm(
+> self,
+> /
+> )
+
+Returns the norm of this Euler Parameter as a scalar.
+
+:rtype: float
+
+
+##### Method `short` {#anise.rotation.Quaternion.short}
+
+> def short(
+> self,
+> /
+> )
+
+Returns the short way rotation of this quaternion
+
+:rtype: Quaternion
+
+
+##### Method `to_dcm` {#anise.rotation.Quaternion.to_dcm}
+
+> def to_dcm(
+> self,
+> /
+> )
+
+Convert this quaterion to a DCM
+:rtype: DCM
+
+
+##### Method `uvec_angle_rad` {#anise.rotation.Quaternion.uvec_angle_rad}
+
+> def uvec_angle_rad(
+> self,
+> /
+> )
+
+Returns the principal line of rotation (a unit vector) and the angle of rotation in radians
+
+:rtype: tuple
+
-----
Generated by *pdoc* 0.11.6 ().
diff --git a/docs/anise/reference/api/python/time.md b/docs/anise/reference/api/python/time.md
index f49f85f..0be1786 100644
--- a/docs/anise/reference/api/python/time.md
+++ b/docs/anise/reference/api/python/time.md
@@ -1,3 +1,18 @@
+---
+description: |
+ API documentation for modules: anise.time.
+
+lang: en
+
+classoption: oneside
+geometry: margin=1in
+papersize: a4
+
+linkcolor: blue
+links-as-notes: true
+...
+
+
# Module `anise.time` {#anise.time}
@@ -19,11 +34,9 @@ Defines generally usable durations for nanosecond precision valid for 32,768 cen
Duration zero minus one nanosecond returns a century of -1 and a nanosecond set to the number of nanoseconds in one century minus one.
That difference is exactly 1 nanoseconds, where the former duration is "closer to zero" than the latter.
As such, the largest negative duration that can be represented sets the centuries to i16::MAX and its nanoseconds to NANOSECONDS_PER_CENTURY.
-2. It was also decided that opposite durations are equal, e.g. -15 minutes == 15 minutes. If the direction of time matters, use the signum function.
+2. Negative and positive durations are distinct: -15 minutes != 15 minutes. Use the signum function to check the sign, and abs() to get the absolute value.
-(Python documentation hints)
:type string_repr: str
-:rtype: Duration
#### Methods
@@ -137,7 +150,7 @@ assert_eq!(two_hours_three_min.ceil(1.hours() + 5.minutes()), 2.hours() + 10.min
Decomposes a Duration in its sign, days, hours, minutes, seconds, ms, us, ns
-:rtype: typing.Tuple
+:rtype: tuple[int, int, int, int, int, int, int, int]
##### Method `floor` {#anise.time.Duration.floor}
@@ -193,6 +206,72 @@ Creates a new duration from its parts
:rtype: Duration
+##### Method `from_days` {#anise.time.Duration.from_days}
+
+> def from_days(
+> value
+> )
+
+Creates a new duration from the provided number of days
+:type value: float
+:rtype: Duration
+
+
+##### Method `from_hours` {#anise.time.Duration.from_hours}
+
+> def from_hours(
+> value
+> )
+
+Creates a new duration from the provided number of hours
+:type value: float
+:rtype: Duration
+
+
+##### Method `from_microseconds` {#anise.time.Duration.from_microseconds}
+
+> def from_microseconds(
+> value
+> )
+
+Creates a new duration from the provided number of microseconds
+:type value: float
+:rtype: Duration
+
+
+##### Method `from_milliseconds` {#anise.time.Duration.from_milliseconds}
+
+> def from_milliseconds(
+> value
+> )
+
+Creates a new duration from the provided number of milliseconds
+:type value: float
+:rtype: Duration
+
+
+##### Method `from_minutes` {#anise.time.Duration.from_minutes}
+
+> def from_minutes(
+> value
+> )
+
+Creates a new duration from the provided number of minutes
+:type value: float
+:rtype: Duration
+
+
+##### Method `from_nanoseconds` {#anise.time.Duration.from_nanoseconds}
+
+> def from_nanoseconds(
+> value
+> )
+
+Creates a new duration from the provided number of nanoseconds
+:type value: float
+:rtype: Duration
+
+
##### Method `from_parts` {#anise.time.Duration.from_parts}
> def from_parts(
@@ -206,6 +285,17 @@ Create a normalized duration from its parts
:rtype: Duration
+##### Method `from_seconds` {#anise.time.Duration.from_seconds}
+
+> def from_seconds(
+> value
+> )
+
+Creates a new duration from the provided number of seconds
+:type value: float
+:rtype: Duration
+
+
##### Method `from_total_nanoseconds` {#anise.time.Duration.from_total_nanoseconds}
> def from_total_nanoseconds(
@@ -326,7 +416,7 @@ Returns the sign of this duration
Returns the centuries and nanoseconds of this duration
NOTE: These items are not public to prevent incorrect durations from being created by modifying the values of the structure directly.
-:rtype: typing.Tuple
+:rtype: tuple[int, int]
##### Method `to_seconds` {#anise.time.Duration.to_seconds}
@@ -390,7 +480,6 @@ Refer to the appropriate functions for initializing this Epoch from different ti
(Python documentation hints)
:type string_repr: str
-:rtype: Epoch
#### Instance variables
@@ -440,6 +529,24 @@ assert_eq!(
:rtype: Epoch
+##### Method `day_of_month` {#anise.time.Epoch.day_of_month}
+
+> def day_of_month(
+> self,
+> /
+> )
+
+Returns the number of days since the start of the Gregorian month in the current time scale.
+
+##### Example
+```
+use hifitime::Epoch;
+let dt = Epoch::from_gregorian_tai_at_midnight(2025, 7, 3);
+assert_eq!(dt.day_of_month(), 3);
+```
+:rtype: int
+
+
##### Method `day_of_year` {#anise.time.Epoch.day_of_year}
> def day_of_year(
@@ -529,6 +636,17 @@ defined as January 1st 2006 (cf. def from_datetime(
+> dt
+> )
+
+Builds an Epoch in UTC from the provided datetime after timezone correction if any is present.
+:type dt: datetime.datetime
+:rtype: Epoch
+
+
##### Method `from_et_duration` {#anise.time.Epoch.from_et_duration}
> def from_et_duration(
@@ -968,6 +1086,20 @@ Initialize an Epoch from the provided UNIX second timestamp since UTC midnight 1
:rtype: Epoch
+##### Method `from_ut1_duration` {#anise.time.Epoch.from_ut1_duration}
+
+> def from_ut1_duration(
+> duration,
+> provider
+> )
+
+Initialize a new Epoch from a duration in UT1
+
+:type duration: Duration
+:type provider: Ut1Provider
+:rtype: Epoch
+
+
##### Method `from_utc_days` {#anise.time.Epoch.from_utc_days}
> def from_utc_days(
@@ -996,7 +1128,7 @@ Initialize an Epoch from the provided UTC seconds since 1900 January 01 at midni
> dt
> )
-Builds an Epoch in UTC from the provided datetime after timezone correction if any is present.
+Builds an Epoch in UTC from the provided datetime. Datetime must either NOT have any timezone, or timezone MUST be UTC.
:type dt: datetime.datetime
:rtype: Epoch
@@ -1983,6 +2115,20 @@ Returns seconds past BDT (BeiDou) Time Epoch
:rtype: float
+##### Method `to_datetime` {#anise.time.Epoch.to_datetime}
+
+> def to_datetime(
+> self,
+> /,
+> set_tz=None
+> )
+
+Returns a Python datetime object from this Epoch (truncating the nanoseconds away)
+If set_tz is True, then this will return a time zone aware datetime object
+:type set_tz: bool or None, optional
+:rtype: datetime.datetime
+
+
##### Method `to_duration_in_time_scale` {#anise.time.Epoch.to_duration_in_time_scale}
> def to_duration_in_time_scale(
@@ -2093,6 +2239,21 @@ Returns seconds past GPS Time Epoch, defined as UTC midnight of January 5th to 6
:rtype: float
+##### Method `to_gregorian` {#anise.time.Epoch.to_gregorian}
+
+> def to_gregorian(
+> self,
+> /,
+> time_scale=None
+> )
+
+Converts the Epoch to the Gregorian parts in the (optionally) provided time scale as (year, month, day, hour, minute, second).
+
+:type time_scale: TimeScale, optional
+
+:rtype: tuple[int, int, int, int, int, int, int]
+
+
##### Method `to_gst_days` {#anise.time.Epoch.to_gst_days}
> def to_gst_days(
@@ -2516,7 +2677,7 @@ Returns this time in a Duration past J1900 counted in TAI
> )
Returns the TAI parts of this duration
-:rtype: typing.Tuple
+:rtype: tuple
##### Method `to_tai_seconds` {#anise.time.Epoch.to_tai_seconds}
@@ -2530,6 +2691,50 @@ Returns the number of TAI seconds since J1900
:rtype: float
+##### Method `to_tcb_duration` {#anise.time.Epoch.to_tcb_duration}
+
+> def to_tcb_duration(
+> self,
+> /
+> )
+
+Returns the Barycentric Coordinate Time (TCB) as a Duration its reference epoch (1977-01-01 + 65.5 µs)
+:rtype: Duration
+
+
+##### Method `to_tcb_seconds` {#anise.time.Epoch.to_tcb_seconds}
+
+> def to_tcb_seconds(
+> self,
+> /
+> )
+
+Returns the Barycentric Coordinate Time (TCB) as seconds its reference epoch (1977-01-01 + 65.5 µs)
+:rtype: float
+
+
+##### Method `to_tcg_duration` {#anise.time.Epoch.to_tcg_duration}
+
+> def to_tcg_duration(
+> self,
+> /
+> )
+
+Returns the Geocentric Coordinate Time (TCG) as a Duration its reference epoch (1977-01-01)
+:rtype: Duration
+
+
+##### Method `to_tcg_seconds` {#anise.time.Epoch.to_tcg_seconds}
+
+> def to_tcg_seconds(
+> self,
+> /
+> )
+
+Returns the Geocentric Coordinate Time (TCG) as seconds its reference epoch (1977-01-01)
+:rtype: float
+
+
##### Method `to_tdb_centuries_since_j2000` {#anise.time.Epoch.to_tdb_centuries_since_j2000}
> def to_tdb_centuries_since_j2000(
@@ -2598,7 +2803,7 @@ Returns the Dynamic Barycentric Time (TDB) (higher fidelity SPICE ephemeris time
Converts this epoch into the time of week, represented as a rolling week counter into that time scale
and the number of nanoseconds elapsed in current week (since closest Sunday midnight).
This is usually how GNSS receivers describe a timestamp.
-:rtype: typing.Tuple[int]
+:rtype: tuple
##### Method `to_time_scale` {#anise.time.Epoch.to_time_scale}
@@ -2730,6 +2935,34 @@ Returns the number seconds since the UNIX epoch defined 01 Jan 1970 midnight UTC
:rtype: float
+##### Method `to_ut1` {#anise.time.Epoch.to_ut1}
+
+> def to_ut1(
+> self,
+> /,
+> provider
+> )
+
+Convert this epoch to Ut1
+
+:type provider: Ut1Provider
+:rtype: Epoch
+
+
+##### Method `to_ut1_duration` {#anise.time.Epoch.to_ut1_duration}
+
+> def to_ut1_duration(
+> self,
+> /,
+> provider
+> )
+
+Returns this time in a Duration past J1900 counted in UT1
+
+:type provider: Ut1Provider
+:rtype: Duration
+
+
##### Method `to_utc` {#anise.time.Epoch.to_utc}
> def to_utc(
@@ -2780,13 +3013,30 @@ Returns the number of UTC seconds since the TAI epoch
> def todatetime(
> self,
-> /
+> /,
+> set_tz=None
> )
-Returns a Python datetime object from this Epoch (truncating the nanoseconds away)
+Returns a Python datetime object from this Epoch (truncating the nanoseconds away).
+If set_tz is True, then this will return a time zone aware datetime object
+:type set_tz: bool or None, optional
:rtype: datetime.datetime
+##### Method `ut1_offset` {#anise.time.Epoch.ut1_offset}
+
+> def ut1_offset(
+> self,
+> /,
+> provider
+> )
+
+Get the accumulated offset between this epoch and UT1.
+
+:type provider: Ut1Provider
+:rtype: Duration
+
+
##### Method `weekday` {#anise.time.Epoch.weekday}
> def weekday(
@@ -2824,6 +3074,124 @@ Returns weekday in UTC timescale
:rtype: Weekday
+##### Method `with_hms` {#anise.time.Epoch.with_hms}
+
+> def with_hms(
+> self,
+> /,
+> hours,
+> minutes,
+> seconds
+> )
+
+Returns a copy of self where the time is set to the provided hours, minutes, seconds
+Invalid number of hours, minutes, and seconds will overflow into their higher unit.
+Warning: this does _not_ set the subdivisions of second to zero.
+:type hours: int
+:type minutes: int
+:type seconds: int
+:rtype: Epoch
+
+
+##### Method `with_hms_from` {#anise.time.Epoch.with_hms_from}
+
+> def with_hms_from(
+> self,
+> /,
+> other
+> )
+
+Returns a copy of self where the hours, minutes, seconds is set to the time of the provided epoch but the
+sub-second parts are kept from the current epoch.
+
+:type other: Epoch
+:rtype: Epoch
+```
+use hifitime::prelude::*;
+
+let epoch = Epoch::from_gregorian_utc(2022, 12, 01, 10, 11, 12, 13);
+let other_utc = Epoch::from_gregorian_utc(2024, 12, 01, 20, 21, 22, 23);
+let other = other_utc.to_time_scale(TimeScale::TDB);
+
+assert_eq!(
+ epoch.with_hms_from(other),
+ Epoch::from_gregorian_utc(2022, 12, 01, 20, 21, 22, 13)
+);
+```
+
+
+##### Method `with_hms_strict` {#anise.time.Epoch.with_hms_strict}
+
+> def with_hms_strict(
+> self,
+> /,
+> hours,
+> minutes,
+> seconds
+> )
+
+Returns a copy of self where the time is set to the provided hours, minutes, seconds
+Invalid number of hours, minutes, and seconds will overflow into their higher unit.
+Warning: this will set the subdivisions of seconds to zero.
+:type hours: int
+:type minutes: int
+:type seconds: int
+:rtype: Epoch
+
+
+##### Method `with_hms_strict_from` {#anise.time.Epoch.with_hms_strict_from}
+
+> def with_hms_strict_from(
+> self,
+> /,
+> other
+> )
+
+Returns a copy of self where the time is set to the time of the other epoch but the subseconds are set to zero.
+
+:type other: Epoch
+:rtype: Epoch
+```
+use hifitime::prelude::*;
+
+let epoch = Epoch::from_gregorian_utc(2022, 12, 01, 10, 11, 12, 13);
+let other_utc = Epoch::from_gregorian_utc(2024, 12, 01, 20, 21, 22, 23);
+let other = other_utc.to_time_scale(TimeScale::TDB);
+
+assert_eq!(
+ epoch.with_hms_strict_from(other),
+ Epoch::from_gregorian_utc(2022, 12, 01, 20, 21, 22, 0)
+);
+```
+
+
+##### Method `with_time_from` {#anise.time.Epoch.with_time_from}
+
+> def with_time_from(
+> self,
+> /,
+> other
+> )
+
+Returns a copy of self where all of the time components (hours, minutes, seconds, and sub-seconds) are set to the time of the provided epoch.
+
+:type other: Epoch
+:rtype: Epoch
+```
+use hifitime::prelude::*;
+
+let epoch = Epoch::from_gregorian_utc(2022, 12, 01, 10, 11, 12, 13);
+let other_utc = Epoch::from_gregorian_utc(2024, 12, 01, 20, 21, 22, 23);
+// If the other Epoch is in another time scale, it does not matter, it will be converted to the correct time scale.
+let other = other_utc.to_time_scale(TimeScale::TDB);
+
+assert_eq!(
+ epoch.with_time_from(other),
+ Epoch::from_gregorian_utc(2022, 12, 01, 20, 21, 22, 23)
+);
+```
+
+
##### Method `year` {#anise.time.Epoch.year}
> def year(
@@ -2843,7 +3211,7 @@ Returns the number of Gregorian years of this epoch in the current time scale.
> )
Returns the year and the days in the year so far (days of year).
-:rtype: typing.Tuple
+:rtype: tuple
### Class `HifitimeError` {#anise.time.HifitimeError}
@@ -2864,11 +3232,32 @@ Returns the year and the days in the year so far (days of year).
> class LatestLeapSeconds
-List of leap seconds from .
+List of leap seconds from .
This list corresponds the number of seconds in TAI to the UTC offset and to whether it was an announced leap second or not.
The unannoucned leap seconds come from dat.c in the SOFA library.
+#### Methods
+
+
+##### Method `is_up_to_date` {#anise.time.LatestLeapSeconds.is_up_to_date}
+
+> def is_up_to_date(
+> self,
+> /
+> )
+
+Downloads the latest leap second list from IANA, and returns whether the embedded leap seconds are still up to date
+
+```
+use hifitime::leap_seconds::LatestLeapSeconds;
+
+assert!(LatestLeapSeconds::default().is_up_to_date().unwrap(), "Hifitime needs to update its leap seconds list!");
+```
+
+:rtype: bool
+
+
### Class `LeapSecondsFile` {#anise.time.LeapSecondsFile}
> class LeapSecondsFile(
@@ -2877,17 +3266,19 @@ The unannoucned leap seconds come from dat.c in the SOFA library.
A leap second provider that uses an IERS formatted leap seconds file.
-(Python documentation hints)
:type path: str
-:rtype: LeapSecondsFile
### Class `MonthName` {#anise.time.MonthName}
> class MonthName(
-> ...
+> month
> )
+Defines Month names, can be initialized either from its variant or its integer (1 for January).
+
+:type month: int
+
#### Class variables
@@ -2944,19 +3335,11 @@ A leap second provider that uses an IERS formatted leap seconds file.
### Class `Polynomial` {#anise.time.Polynomial}
-> class Polynomial(
-> ...
-> )
+> class Polynomial
Interpolation [Polynomial] used for example in [TimeScale]
maintenance, precise monitoring or conversions.
-(Python documentation hints)
-:type constant: Duration
-:type rate: Duration
-:type accel: Duration
-:rtype: Polynomial
-
#### Methods
@@ -3025,9 +3408,7 @@ Create a [Polynomial] structure from a static offset and drift, in nanoseconds a
### Class `TimeScale` {#anise.time.TimeScale}
-> class TimeScale(
-> ...
-> )
+> class TimeScale
Enum of the different time systems available
@@ -3053,9 +3434,21 @@ Enum of the different time systems available
##### Variable `TAI` {#anise.time.TimeScale.TAI}
+##### Variable `TCB` {#anise.time.TimeScale.TCB}
+
+
+##### Variable `TCG` {#anise.time.TimeScale.TCG}
+
+
+##### Variable `TCL` {#anise.time.TimeScale.TCL}
+
+
##### Variable `TDB` {#anise.time.TimeScale.TDB}
+##### Variable `TL` {#anise.time.TimeScale.TL}
+
+
##### Variable `TT` {#anise.time.TimeScale.TT}
@@ -3092,14 +3485,11 @@ An iterator of a sequence of evenly spaced Epochs.
:type end: Epoch
:type step: Duration
:type inclusive: bool
-:rtype: TimeSeries
### Class `Unit` {#anise.time.Unit}
-> class Unit(
-> ...
-> )
+> class Unit
An Enum to perform time unit conversions.
@@ -3160,12 +3550,50 @@ An Enum to perform time unit conversions.
A structure storing all of the TAI-UT1 data
-### Class `Weekday` {#anise.time.Weekday}
+#### Instance variables
+
+
+##### Variable `data` {#anise.time.Ut1Provider.data}
+
+vector of Delta TAI-UT1 values
+:rtype: list
+
+
+##### Variable `iter_pos` {#anise.time.Ut1Provider.iter_pos}
+
+current position of the iterator
+:rtype: int
-> class Weekday(
-> ...
+
+#### Methods
+
+
+##### Method `as_list` {#anise.time.Ut1Provider.as_list}
+
+> def as_list(
+> self,
+> /
> )
+Returns the list of Delta TAI-UT1 values
+:rtype: list
+
+
+##### Method `from_eop_file` {#anise.time.Ut1Provider.from_eop_file}
+
+> def from_eop_file(
+> path
+> )
+
+Builds a UT1 provider from the provided path to an EOP file.
+:type path: str
+:rtype: Ut1Provider
+
+
+### Class `Weekday` {#anise.time.Weekday}
+
+> class Weekday
+
#### Class variables
diff --git a/docs/anise/reference/api/python/utils.md b/docs/anise/reference/api/python/utils.md
index 65942f0..e85f04e 100644
--- a/docs/anise/reference/api/python/utils.md
+++ b/docs/anise/reference/api/python/utils.md
@@ -1,3 +1,18 @@
+---
+description: |
+ API documentation for modules: anise.utils.
+
+lang: en
+
+classoption: oneside
+geometry: margin=1in
+papersize: a4
+
+linkcolor: blue
+links-as-notes: true
+...
+
+
# Module `anise.utils` {#anise.utils}
diff --git a/mkdocs.yml b/mkdocs.yml
index 97dfb8b..a58a58d 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -129,6 +129,7 @@ nav:
- ANISE Python: anise/reference/api/python/index.md
- Astro: anise/reference/api/python/astro.md
- Constants: anise/reference/api/python/constants.md
+ - Rotation: anise/reference/api/python/rotation.md
- Time: anise/reference/api/python/time.md
- Utils: anise/reference/api/python/utils.md
- Rust API: anise/reference/api/rust/index.md
@@ -160,9 +161,6 @@ repo_name: nyx-space/nyx
extra:
social:
- - icon: material/comment-multiple
- link: https://app.element.io/#/room/#astrodyn:matrix.org
- name: Astrodynamics on Matrix.org
- icon: material/linkedin
link: https://www.linkedin.com/in/chrisrabotin/
name: Chris Rabotin on LinkedIn