Skip to content

Commit 208b72c

Browse files
Update pyi file
1 parent a571428 commit 208b72c

File tree

6 files changed

+213
-13
lines changed

6 files changed

+213
-13
lines changed

anise-py/anise.pyi

Lines changed: 147 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ This function performs a memory allocation."""
107107
# Warning
108108
This function performs a memory allocation."""
109109

110-
def describe(self, spk: bool=None, bpc: bool=None, planetary: bool=None, time_scale: TimeScale=None, round_time: bool=None) -> None:
110+
def describe(self, spk: bool=None, bpc: bool=None, planetary: bool=None, eulerparams: bool=None, time_scale: TimeScale=None, round_time: bool=None) -> None:
111111
"""Pretty prints the description of this Almanac, showing everything by default. Default time scale is TDB.
112112
If any parameter is set to true, then nothing other than that will be printed."""
113113

@@ -159,6 +159,20 @@ A 100% percent occultation means that the back object is fully hidden from the
159159
A value in between means that the back object is partially hidden from the observser (i.e. _penumbra_ if the back object is the Sun).
160160
Refer to the [MathSpec](https://nyxspace.com/nyxspace/MathSpec/celestial/eclipse/) for modeling details."""
161161

162+
def rotate(self, from_frame: Frame, to_frame: Frame, epoch: Epoch) -> DCM:
163+
"""Returns the 6x6 DCM needed to rotation the `from_frame` to the `to_frame`.
164+
165+
# Warning
166+
This function only performs the rotation and no translation whatsoever. Use the `transform_from_to` function instead to include rotations.
167+
168+
# Note
169+
This function performs a recursion of no more than twice the MAX_TREE_DEPTH."""
170+
171+
def rotate_to(self, state: CartesianState, observer_frame: Frame) -> CartesianState:
172+
"""Rotates the provided Cartesian state into the requested observer frame
173+
174+
**WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the `transform_to` function instead to include rotations."""
175+
162176
def solar_eclipsing(self, eclipsing_frame: Frame, observer: Orbit, ab_corr: Aberration=None) -> Occultation:
163177
"""Computes the solar eclipsing of the observer due to the eclipsing_frame.
164178
@@ -183,7 +197,7 @@ This function performs a memory allocation."""
183197
# Warning
184198
This function performs a memory allocation."""
185199

186-
def state_of(self, object: int, observer: Frame, epoch: Epoch, ab_corr: Aberration=None) -> Orbit:
200+
def state_of(self, object_id: int, observer: Frame, epoch: Epoch, ab_corr: Aberration=None) -> Orbit:
187201
"""Returns the Cartesian state of the object as seen from the provided observer frame (essentially `spkezr`).
188202
189203
# Note
@@ -407,8 +421,6 @@ This function modified `self` and changes the URI to be the path to the download
407421

408422
@typing.final
409423
class astro:
410-
_all__: list = ["constants", "AzElRange", "Ellipsoid", "Occultation", "Orbit"]
411-
412424
@typing.final
413425
class AzElRange:
414426
"""A structure that stores the result of Azimuth, Elevation, Range, Range rate calculation."""
@@ -716,6 +728,127 @@ class astro:
716728
def c3_km2_s2(self) -> float:
717729
"""Returns the $C_3$ of this orbit in km^2/s^2"""
718730

731+
def cartesian_pos_vel(self) -> numpy.array:
732+
"""Returns this state as a Cartesian vector of size 6 in [km, km, km, km/s, km/s, km/s]
733+
734+
Note that the time is **not** returned in the vector."""
735+
736+
def dcm3x3_from_rcn_to_inertial(self) -> DCM:
737+
"""Builds the rotation matrix that rotates from this state's inertial frame to this state's RCN frame (radial, cross, normal)
738+
739+
# Frame warning
740+
If the stattion is NOT in an inertial frame, then this computation is INVALID.
741+
742+
# Algorithm
743+
1. Compute \\hat{r}, \\hat{h}, the unit vectors of the radius and orbital momentum.
744+
2. Compute the cross product of these
745+
3. Build the DCM with these unit vectors
746+
4. Return the DCM structure"""
747+
748+
def dcm3x3_from_ric_to_inertial(self) -> DCM:
749+
"""Builds the rotation matrix that rotates from this state's inertial frame to this state's RIC frame
750+
751+
# Frame warning
752+
If the state is NOT in an inertial frame, then this computation is INVALID.
753+
754+
# Algorithm
755+
1. Build the c vector as the normalized orbital momentum vector
756+
2. Build the i vector as the cross product of \\hat{r} and c
757+
3. Build the RIC DCM as a 3x3 of the columns [\\hat{r}, \\hat{i}, \\hat{c}]
758+
4. Return the DCM structure **without** accounting for the transport theorem."""
759+
760+
def dcm3x3_from_topocentric_to_body_fixed(self) -> DCM:
761+
"""Builds the rotation matrix that rotates from the topocentric frame (SEZ) into the body fixed frame of this state.
762+
763+
# Frame warning
764+
If the state is NOT in a body fixed frame (i.e. ITRF93), then this computation is INVALID.
765+
766+
# Source
767+
From the GMAT MathSpec, page 30 section 2.6.9 and from `Calculate_RFT` in `TopocentricAxes.cpp`, this returns the
768+
rotation matrix from the topocentric frame (SEZ) to body fixed frame.
769+
In the GMAT MathSpec notation, R_{IF} is the DCM from body fixed to inertial. Similarly, R{FT} is from topocentric
770+
to body fixed."""
771+
772+
def dcm3x3_from_vnc_to_inertial(self) -> DCM:
773+
"""Builds the rotation matrix that rotates from this state's inertial frame to this state's VNC frame (velocity, normal, cross)
774+
775+
# Frame warning
776+
If the stattion is NOT in an inertial frame, then this computation is INVALID.
777+
778+
# Algorithm
779+
1. Compute \\hat{v}, \\hat{h}, the unit vectors of the radius and orbital momentum.
780+
2. Compute the cross product of these
781+
3. Build the DCM with these unit vectors
782+
4. Return the DCM structure."""
783+
784+
def dcm_from_rcn_to_inertial(self) -> DCM:
785+
"""Builds the rotation matrix that rotates from this state's inertial frame to this state's RCN frame (radial, cross, normal)
786+
787+
# Frame warning
788+
If the stattion is NOT in an inertial frame, then this computation is INVALID.
789+
790+
# Algorithm
791+
1. Compute \\hat{r}, \\hat{h}, the unit vectors of the radius and orbital momentum.
792+
2. Compute the cross product of these
793+
3. Build the DCM with these unit vectors
794+
4. Return the DCM structure with a 6x6 DCM with the time derivative of the VNC frame set.
795+
796+
# Note on the time derivative
797+
If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set.
798+
Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame."""
799+
800+
def dcm_from_ric_to_inertial(self) -> DCM:
801+
"""Builds the rotation matrix that rotates from this state's inertial frame to this state's RIC frame
802+
803+
# Frame warning
804+
If the state is NOT in an inertial frame, then this computation is INVALID.
805+
806+
# Algorithm
807+
1. Compute the state data one millisecond before and one millisecond assuming two body dynamics
808+
2. Compute the DCM for this state, and the pre and post states
809+
3. Build the c vector as the normalized orbital momentum vector
810+
4. Build the i vector as the cross product of \\hat{r} and c
811+
5. Build the RIC DCM as a 3x3 of the columns [\\hat{r}, \\hat{i}, \\hat{c}], for the post, post, and current states
812+
6. Compute the difference between the DCMs of the pre and post states, to build the DCM time derivative
813+
7. Return the DCM structure with a 6x6 state DCM.
814+
815+
# Note on the time derivative
816+
If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set.
817+
Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame."""
818+
819+
def dcm_from_topocentric_to_body_fixed(self, _from: float) -> DCM:
820+
"""Builds the rotation matrix that rotates from the topocentric frame (SEZ) into the body fixed frame of this state.
821+
822+
# Frame warnings
823+
+ If the state is NOT in a body fixed frame (i.e. ITRF93), then this computation is INVALID.
824+
+ (Usually) no time derivative can be computed: the orbit is expected to be a body fixed frame where the `at_epoch` function will fail. Exceptions for Moon body fixed frames.
825+
826+
# UNUSED Arguments
827+
+ `from`: ID of this new frame. Only used to set the "from" frame of the DCM. -- No longer used since 0.5.3
828+
829+
# Source
830+
From the GMAT MathSpec, page 30 section 2.6.9 and from `Calculate_RFT` in `TopocentricAxes.cpp`, this returns the
831+
rotation matrix from the topocentric frame (SEZ) to body fixed frame.
832+
In the GMAT MathSpec notation, R_{IF} is the DCM from body fixed to inertial. Similarly, R{FT} is from topocentric
833+
to body fixed."""
834+
835+
def dcm_from_vnc_to_inertial(self) -> DCM:
836+
"""Builds the rotation matrix that rotates from this state's inertial frame to this state's VNC frame (velocity, normal, cross)
837+
838+
# Frame warning
839+
If the stattion is NOT in an inertial frame, then this computation is INVALID.
840+
841+
# Algorithm
842+
1. Compute \\hat{v}, \\hat{h}, the unit vectors of the radius and orbital momentum.
843+
2. Compute the cross product of these
844+
3. Build the DCM with these unit vectors
845+
4. Compute the difference between the DCMs of the pre and post states (+/- 1 ms), to build the DCM time derivative
846+
4. Return the DCM structure with a 6x6 DCM with the time derivative of the VNC frame set.
847+
848+
# Note on the time derivative
849+
If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set.
850+
Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame."""
851+
719852
def declination_deg(self) -> float:
720853
"""Returns the declination of this orbit in degrees"""
721854

@@ -1023,6 +1156,7 @@ class astro:
10231156
def __str__(self) -> str:
10241157
"""Return str(self)."""
10251158

1159+
@typing.final
10261160
class constants:
10271161
@typing.final
10281162
class CelestialObjects:
@@ -1065,7 +1199,11 @@ class astro:
10651199
MARS_BARYCENTER_J2000: Frame = ...
10661200
MERCURY_J2000: Frame = ...
10671201
MOON_J2000: Frame = ...
1202+
MOON_ME_DE421_FRAME: Frame = ...
1203+
MOON_ME_DE440_ME421_FRAME: Frame = ...
10681204
MOON_ME_FRAME: Frame = ...
1205+
MOON_PA_DE421_FRAME: Frame = ...
1206+
MOON_PA_DE440_FRAME: Frame = ...
10691207
MOON_PA_FRAME: Frame = ...
10701208
NEPTUNE_BARYCENTER_J2000: Frame = ...
10711209
PLUTO_BARYCENTER_J2000: Frame = ...
@@ -1090,14 +1228,19 @@ class astro:
10901228
ITRF93: int = ...
10911229
J2000: int = ...
10921230
MOON_ME: int = ...
1231+
MOON_ME_DE421: int = ...
1232+
MOON_ME_DE440_ME421: int = ...
10931233
MOON_PA: int = ...
1234+
MOON_PA_DE421: int = ...
1235+
MOON_PA_DE440: int = ...
10941236

10951237
@typing.final
10961238
class UsualConstants:
10971239
MEAN_EARTH_ANGULAR_VELOCITY_DEG_S: float = ...
10981240
MEAN_MOON_ANGULAR_VELOCITY_DEG_S: float = ...
10991241
SPEED_OF_LIGHT_KM_S: float = ...
11001242

1243+
11011244
@typing.final
11021245
class time:
11031246
@typing.final
@@ -2201,10 +2344,8 @@ KPL/TPC files must be converted into "PCA" (Planetary Constant ANISE) files befo
22012344
__all__: list = ...
22022345
__name__: str = ...
22032346

2204-
22052347
@typing.final
22062348
class rotation:
2207-
22082349
@typing.final
22092350
class DCM:
22102351
"""Defines a direction cosine matrix from one frame ID to another frame ID, optionally with its time derivative.

anise/src/almanac/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,7 @@ impl Almanac {
220220
})
221221
}
222222
}
223-
}
224223

225-
impl Almanac {
226224
/// Generic function that tries to load the provided path guessing to the file type.
227225
pub fn load(&self, path: &str) -> AlmanacResult<Self> {
228226
// Load the data onto the heap

anise/src/almanac/python.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ use crate::{
1616
astro::{Aberration, AzElRange, Occultation},
1717
ephemerides::EphemerisError,
1818
errors::AlmanacResult,
19-
math::cartesian::CartesianState,
19+
math::{cartesian::CartesianState, rotation::DCM},
20+
orientations::OrientationError,
2021
prelude::{Frame, Orbit},
2122
NaifId,
2223
};
@@ -59,6 +60,7 @@ impl Almanac {
5960
/// :type spk: bool, optional
6061
/// :type bpc: bool, optional
6162
/// :type planetary: bool, optional
63+
/// :type eulerparams: bool, optional
6264
/// :type time_scale: TimeScale, optional
6365
/// :type round_time: bool, optional
6466
/// :rtype: None
@@ -410,4 +412,50 @@ impl Almanac {
410412
) -> Result<CartesianState, EphemerisError> {
411413
self.translate_to(state, observer_frame, ab_corr)
412414
}
415+
416+
/// Returns the 6x6 DCM needed to rotation the `from_frame` to the `to_frame`.
417+
///
418+
/// # Warning
419+
/// This function only performs the rotation and no translation whatsoever. Use the `transform_from_to` function instead to include rotations.
420+
///
421+
/// # Note
422+
/// This function performs a recursion of no more than twice the MAX_TREE_DEPTH.
423+
///
424+
/// :type from_frame: Frame
425+
/// :type to_frame: Frame
426+
/// :type epoch: Epoch
427+
/// :rtype: DCM
428+
#[pyo3(name = "rotate", signature=(
429+
from_frame,
430+
to_frame,
431+
epoch,
432+
))]
433+
pub fn py_rotate(
434+
&self,
435+
from_frame: Frame,
436+
to_frame: Frame,
437+
epoch: Epoch,
438+
) -> Result<DCM, OrientationError> {
439+
self.rotate(from_frame, to_frame, epoch)
440+
}
441+
442+
/// Rotates the provided Cartesian state into the requested observer frame
443+
///
444+
/// **WARNING:** This function only performs the translation and no rotation _whatsoever_. Use the `transform_to` function instead to include rotations.
445+
///
446+
/// :type state: CartesianState
447+
/// :type observer_frame: Frame
448+
/// :rtype: CartesianState
449+
#[pyo3(name = "rotate_to", signature=(
450+
state,
451+
observer_frame,
452+
))]
453+
#[allow(clippy::too_many_arguments)]
454+
pub fn py_rotate_to(
455+
&self,
456+
state: CartesianState,
457+
observer_frame: Frame,
458+
) -> Result<CartesianState, OrientationError> {
459+
self.rotate_to(state, observer_frame)
460+
}
413461
}

anise/src/astro/orbit.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ impl Orbit {
334334
/// rotation matrix from the topocentric frame (SEZ) to body fixed frame.
335335
/// In the GMAT MathSpec notation, R_{IF} is the DCM from body fixed to inertial. Similarly, R{FT} is from topocentric
336336
/// to body fixed.
337+
///
338+
/// :type _from: float
339+
/// :rtype: DCM
337340
pub fn dcm_from_topocentric_to_body_fixed(&self, _from: NaifId) -> PhysicsResult<DCM> {
338341
let rot_mat_dt = if let Ok(pre) = self.at_epoch(self.epoch - Unit::Second * 1) {
339342
if let Ok(post) = self.at_epoch(self.epoch + Unit::Second * 1) {
@@ -365,6 +368,8 @@ impl Orbit {
365368
/// rotation matrix from the topocentric frame (SEZ) to body fixed frame.
366369
/// In the GMAT MathSpec notation, R_{IF} is the DCM from body fixed to inertial. Similarly, R{FT} is from topocentric
367370
/// to body fixed.
371+
///
372+
/// :rtype: DCM
368373
pub fn dcm3x3_from_topocentric_to_body_fixed(&self) -> PhysicsResult<DCM> {
369374
if (self.radius_km.x.powi(2) + self.radius_km.y.powi(2)).sqrt() < 1e-3 {
370375
warn!("SEZ frame ill-defined when close to the poles");
@@ -411,6 +416,8 @@ impl Orbit {
411416
/// # Note on the time derivative
412417
/// If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set.
413418
/// Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame.
419+
///
420+
/// :rtype: DCM
414421
pub fn dcm_from_ric_to_inertial(&self) -> PhysicsResult<DCM> {
415422
let rot_mat_dt = if let Ok(pre) = self.at_epoch(self.epoch - Unit::Millisecond * 1) {
416423
if let Ok(post) = self.at_epoch(self.epoch + Unit::Millisecond * 1) {
@@ -442,6 +449,8 @@ impl Orbit {
442449
/// 2. Build the i vector as the cross product of \hat{r} and c
443450
/// 3. Build the RIC DCM as a 3x3 of the columns [\hat{r}, \hat{i}, \hat{c}]
444451
/// 4. Return the DCM structure **without** accounting for the transport theorem.
452+
///
453+
/// :rtype: DCM
445454
pub fn dcm3x3_from_ric_to_inertial(&self) -> PhysicsResult<DCM> {
446455
let r_hat = self.r_hat();
447456
let c_hat = self.hvec()? / self.hmag()?;
@@ -467,6 +476,8 @@ impl Orbit {
467476
/// 2. Compute the cross product of these
468477
/// 3. Build the DCM with these unit vectors
469478
/// 4. Return the DCM structure
479+
///
480+
/// :rtype: DCM
470481
pub fn dcm3x3_from_rcn_to_inertial(&self) -> PhysicsResult<DCM> {
471482
let r = self.r_hat();
472483
let n = self.hvec()? / self.hmag()?;
@@ -496,6 +507,8 @@ impl Orbit {
496507
/// # Note on the time derivative
497508
/// If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set.
498509
/// Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame.
510+
///
511+
/// :rtype: DCM
499512
pub fn dcm_from_rcn_to_inertial(&self) -> PhysicsResult<DCM> {
500513
let rot_mat_dt = if let Ok(pre) = self.at_epoch(self.epoch - Unit::Millisecond * 1) {
501514
if let Ok(post) = self.at_epoch(self.epoch + Unit::Millisecond * 1) {
@@ -528,6 +541,7 @@ impl Orbit {
528541
/// 3. Build the DCM with these unit vectors
529542
/// 4. Return the DCM structure.
530543
///
544+
/// :rtype: DCM
531545
pub fn dcm3x3_from_vnc_to_inertial(&self) -> PhysicsResult<DCM> {
532546
let v = self.velocity_km_s / self.vmag_km_s();
533547
let n = self.hvec()? / self.hmag()?;
@@ -558,6 +572,8 @@ impl Orbit {
558572
/// # Note on the time derivative
559573
/// If the pre or post states cannot be computed, then the time derivative of the DCM will _not_ be set.
560574
/// Further note that most astrodynamics tools do *not* account for the time derivative in the RIC frame.
575+
///
576+
/// :rtype: DCM
561577
pub fn dcm_from_vnc_to_inertial(&self) -> PhysicsResult<DCM> {
562578
let rot_mat_dt = if let Ok(pre) = self.at_epoch(self.epoch - Unit::Millisecond * 1) {
563579
if let Ok(post) = self.at_epoch(self.epoch + Unit::Millisecond * 1) {

anise/src/math/cartesian_py.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ impl CartesianState {
162162
/// Returns this state as a Cartesian vector of size 6 in [km, km, km, km/s, km/s, km/s]
163163
///
164164
/// Note that the time is **not** returned in the vector.
165+
/// :rtype: numpy.array
165166
fn cartesian_pos_vel<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyArray1<f64>>> {
166167
let data: Vec<f64> = self.to_cartesian_pos_vel().iter().copied().collect();
167168

anise/src/orientations/rotations.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ use crate::math::units::*;
2121
use crate::math::Vector3;
2222
use crate::prelude::Frame;
2323

24-
#[cfg(feature = "python")]
25-
use pyo3::prelude::*;
26-
27-
#[cfg_attr(feature = "python", pymethods)]
2824
impl Almanac {
2925
/// Returns the 6x6 DCM needed to rotation the `from_frame` to the `to_frame`.
3026
///

0 commit comments

Comments
 (0)