Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rotations using Euler parameters and MRPs #96

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a5344c5
First try at quaternion library
ChristopherRabotin Jun 27, 2023
ceb5d96
Very basic unit testing for quaternion and MRP
ChristopherRabotin Jun 27, 2023
ff1fccd
Add b matrix for EP and MRP
ChristopherRabotin Jun 29, 2023
4daf236
Clippy
ChristopherRabotin Jun 29, 2023
e537e0a
Started EP to DCM conversion
ChristopherRabotin Jul 2, 2023
6323b00
Add DCM PartialEq
ChristopherRabotin Jul 2, 2023
330bb91
Fix PRV and uvec
ChristopherRabotin Jul 3, 2023
3310aa9
Trivial derivative test
ChristopherRabotin Jul 3, 2023
173ffcd
Enhanced tests
ChristopherRabotin Jul 4, 2023
8f8c6df
Issues crop up when extending tests in rotation
ChristopherRabotin Jul 4, 2023
4f56f49
TODO: Switch from passive to active rotation everywhere
ChristopherRabotin Jul 4, 2023
b98dd14
MRP / EP recip test now ensures short way EP
ChristopherRabotin Jul 7, 2023
ad6342a
Slowly fixing SO(3)
ChristopherRabotin Aug 24, 2023
0fc0221
Rename Context to Almanac
ChristopherRabotin Sep 2, 2023
d7da513
Ha! Found a nice way to load generically
ChristopherRabotin Sep 3, 2023
09acd94
DAF data still loaded on heap, but ANISE dataset may be mmapped
ChristopherRabotin Sep 4, 2023
c542fdc
Add `from_static` for DAF and its test
ChristopherRabotin Sep 4, 2023
8725e53
Fixed rotations, just needed to focus
ChristopherRabotin Sep 8, 2023
3be2f32
Rotations look good
ChristopherRabotin Sep 8, 2023
073fa64
Merge branch 'master' into 35-structures-and-traits-for-rotation-math…
ChristopherRabotin Sep 8, 2023
6ecf861
cargo fmt
ChristopherRabotin Sep 8, 2023
ab26076
clippy fixes
ChristopherRabotin Sep 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ exclude = ["cspice"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
hifitime = {version = "3.8.0"}
hifitime = "3.8"
memmap2 = "0.7.0"
crc32fast = "1.3.0"
der = {version = "0.6.0", features = ["derive", "alloc", "real"]}
Expand All @@ -36,11 +36,11 @@ heapless = "0.7.16"

[dev-dependencies]
rust-spice = "0.7.4"
parquet = "44.0.0"
arrow = "44.0.0"
parquet = "46.0.0"
arrow = "46.0.0"
criterion = "0.5"
iai = "0.1"
polars = {version = "0.30", features = ["lazy", "parquet"]}
polars = {version = "0.32", features = ["lazy", "parquet"]}
rayon = "1.7"

[features]
Expand Down
8 changes: 4 additions & 4 deletions benches/crit_jpl_ephemerides.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anise::{
constants::frames::{EARTH_J2000, LUNA_J2000},
file_mmap,
file2heap,
prelude::*,
};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
Expand All @@ -21,7 +21,7 @@ fn benchmark_spice_single_hop_type2_cheby(time_it: TimeSeries) {
}
}

fn benchmark_anise_single_hop_type2_cheby(ctx: &Context, time_it: TimeSeries) {
fn benchmark_anise_single_hop_type2_cheby(ctx: &Almanac, time_it: TimeSeries) {
for epoch in time_it {
black_box(
ctx.translate_from_to_km_s_geometric(EARTH_J2000, LUNA_J2000, epoch)
Expand All @@ -38,9 +38,9 @@ pub fn criterion_benchmark(c: &mut Criterion) {

// Load ANISE data
let path = "./data/de440s.bsp";
let buf = file_mmap!(path).unwrap();
let buf = file2heap!(path).unwrap();
let spk = SPK::parse(buf).unwrap();
let ctx = Context::from_spk(&spk).unwrap();
let ctx = Almanac::from_spk(&spk).unwrap();

// Load SPICE data
spice::furnsh("data/de440s.bsp");
Expand Down
10 changes: 5 additions & 5 deletions benches/crit_spacecraft_ephemeris.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anise::{constants::frames::EARTH_J2000, file_mmap, prelude::*};
use anise::{constants::frames::EARTH_J2000, file2heap, prelude::*};

use criterion::{black_box, criterion_group, criterion_main, Criterion};

Expand All @@ -23,7 +23,7 @@ fn benchmark_spice_single_hop_type13_hermite(time_it: TimeSeries) {
spice::unload("data/gmat-hermite.bsp");
}

fn benchmark_anise_single_hop_type13_hermite(ctx: &Context, time_it: TimeSeries) {
fn benchmark_anise_single_hop_type13_hermite(ctx: &Almanac, time_it: TimeSeries) {
let my_sc_j2k = Frame::from_ephem_j2000(-10000001);
for epoch in time_it {
black_box(
Expand All @@ -40,13 +40,13 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let time_it = TimeSeries::exclusive(start_epoch, end_epoch - time_step, time_step);

let path = "./data/de440s.bsp";
let buf = file_mmap!(path).unwrap();
let buf = file2heap!(path).unwrap();
let spk = SPK::parse(buf).unwrap();

let buf = file_mmap!("data/gmat-hermite.bsp").unwrap();
let buf = file2heap!("data/gmat-hermite.bsp").unwrap();
let spacecraft = SPK::parse(buf).unwrap();

let ctx = Context::from_spk(&spk)
let ctx = Almanac::from_spk(&spk)
.unwrap()
.load_spk(&spacecraft)
.unwrap();
Expand Down
6 changes: 3 additions & 3 deletions benches/iai_jpl_ephemerides.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anise::{
constants::frames::{EARTH_J2000, LUNA_J2000},
file_mmap,
file2heap,
prelude::*,
};

Expand Down Expand Up @@ -38,9 +38,9 @@ fn benchmark_anise_single_hop_type2_cheby() {
let time_it = TimeSeries::exclusive(start_epoch, end_epoch - time_step, time_step);

let path = "./data/de440s.bsp";
let buf = file_mmap!(path).unwrap();
let buf = file2heap!(path).unwrap();
let spk = SPK::parse(buf).unwrap();
let ctx = Context::from_spk(&spk).unwrap();
let ctx = Almanac::from_spk(&spk).unwrap();

for epoch in time_it {
black_box(
Expand Down
8 changes: 4 additions & 4 deletions benches/iai_spacecraft_ephemeris.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anise::{constants::frames::EARTH_J2000, file_mmap, prelude::*};
use anise::{constants::frames::EARTH_J2000, file2heap, prelude::*};

use iai::black_box;
use spice;
Expand All @@ -24,13 +24,13 @@ fn benchmark_anise_single_hop_type13_hermite() {
let epoch = Epoch::from_gregorian_hms(2000, 1, 1, 14, 0, 0, TimeScale::UTC);

let path = "./data/de440s.bsp";
let buf = file_mmap!(path).unwrap();
let buf = file2heap!(path).unwrap();
let spk = SPK::parse(buf).unwrap();

let buf = file_mmap!("data/gmat-hermite.bsp").unwrap();
let buf = file2heap!("data/gmat-hermite.bsp").unwrap();
let spacecraft = SPK::parse(buf).unwrap();

let ctx = Context::from_spk(&spk)
let ctx = Almanac::from_spk(&spk)
.unwrap()
.load_spk(&spacecraft)
.unwrap();
Expand Down
6 changes: 3 additions & 3 deletions src/context/bpc.rs → src/almanac/bpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ use crate::naif::pck::BPCSummaryRecord;
use crate::naif::BPC;
use log::error;

use super::{Context, MAX_LOADED_BPCS};
use super::{Almanac, MAX_LOADED_BPCS};

impl<'a: 'b, 'b> Context<'a> {
impl<'a: 'b, 'b> Almanac<'a> {
/// Loads a Binary Planetary Constants kernel.
pub fn load_bpc(&self, bpc: &'b BPC) -> Result<Context<'b>, AniseError> {
pub fn load_bpc(&self, bpc: &'b BPC) -> Result<Almanac<'b>, AniseError> {
// This is just a bunch of pointers so it doesn't use much memory.
let mut me = self.clone();
let mut data_idx = MAX_LOADED_BPCS;
Expand Down
6 changes: 3 additions & 3 deletions src/context/mod.rs → src/almanac/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ pub const MAX_PLANETARY_DATA: usize = 64;
pub mod bpc;
pub mod spk;

/// A SPICE context contains all of the loaded SPICE data.
/// An Almanac contains all of the loaded SPICE and ANISE data.
///
/// # Limitations
/// The stack space required depends on the maximum number of each type that can be loaded.
#[derive(Clone, Default)]
pub struct Context<'a> {
pub struct Almanac<'a> {
/// NAIF SPK is kept unchanged
pub spk_data: [Option<&'a SPK>; MAX_LOADED_SPKS],
/// NAIF BPC is kept unchanged
Expand All @@ -39,7 +39,7 @@ pub struct Context<'a> {
pub spacecraft_data: DataSet<'a, SpacecraftData<'a>, MAX_SPACECRAFT_DATA>,
}

impl<'a> fmt::Display for Context<'a> {
impl<'a> fmt::Display for Almanac<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(
f,
Expand Down
8 changes: 4 additions & 4 deletions src/context/spk.rs → src/almanac/spk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ use crate::naif::SPK;
use log::error;

// TODO: Switch these to build constants so that it's configurable when building the library.
use super::{Context, MAX_LOADED_SPKS};
use super::{Almanac, MAX_LOADED_SPKS};

impl<'a: 'b, 'b> Context<'a> {
pub fn from_spk(spk: &'a SPK) -> Result<Context<'a>, AniseError> {
impl<'a: 'b, 'b> Almanac<'a> {
pub fn from_spk(spk: &'a SPK) -> Result<Almanac<'a>, AniseError> {
let me = Self::default();
me.load_spk(spk)
}

/// Loads a new SPK file into a new context.
/// This new context is needed to satisfy the unloading of files. In fact, to unload a file, simply let the newly loaded context drop out of scope and Rust will clean it up.
pub fn load_spk(&self, spk: &'b SPK) -> Result<Context<'b>, AniseError> {
pub fn load_spk(&self, spk: &'b SPK) -> Result<Almanac<'b>, AniseError> {
// This is just a bunch of pointers so it doesn't use much memory.
let mut me = self.clone();
// Parse as SPK and place into the SPK list if there is room
Expand Down
6 changes: 3 additions & 3 deletions src/bin/anise/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use anise::cli::args::{Actions, Args};
use anise::cli::inspect::{BpcRow, SpkRow};
use anise::cli::CliErrors;
use anise::file_mmap;
use anise::file2heap;
use anise::naif::daf::{FileRecord, NAIFRecord, NAIFSummaryRecord};
use anise::naif::kpl::parser::convert_tpc;
use anise::prelude::*;
Expand Down Expand Up @@ -35,7 +35,7 @@
crc32_checksum,
} => {
let path_str = file.clone();
match file_mmap!(file) {
match file2heap!(file) {

Check warning on line 38 in src/bin/anise/main.rs

View check run for this annotation

Codecov / codecov/patch

src/bin/anise/main.rs#L38

Added line #L38 was not covered by tests
Ok(bytes) => {
// Try to load this as a dataset by first trying to load the metadata
if let Ok(metadata) = Metadata::decode_header(&bytes) {
Expand Down Expand Up @@ -107,7 +107,7 @@
}
Actions::Inspect { file } => {
let path_str = file.clone();
match file_mmap!(file) {
match file2heap!(file) {

Check warning on line 110 in src/bin/anise/main.rs

View check run for this annotation

Codecov / codecov/patch

src/bin/anise/main.rs#L110

Added line #L110 was not covered by tests
Ok(bytes) => {
// Load the header only
let file_record = FileRecord::read_from(&bytes[..FileRecord::SIZE]).unwrap();
Expand Down
4 changes: 2 additions & 2 deletions src/ephemerides/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use hifitime::Epoch;
use log::error;

use crate::context::Context;
use crate::almanac::Almanac;
use crate::errors::InternalErrorKind;
use crate::naif::daf::NAIFSummaryRecord;
use crate::NaifId;
Expand All @@ -23,7 +23,7 @@ use crate::{
/// **Limitation:** no translation or rotation may have more than 8 nodes.
pub const MAX_TREE_DEPTH: usize = 8;

impl<'a> Context<'a> {
impl<'a> Almanac<'a> {
/// Returns the center of all of the loaded ephemerides, typically this should be the Solar System Barycenter.
///
/// # Algorithm
Expand Down
4 changes: 2 additions & 2 deletions src/ephemerides/translate_to_parent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

use log::trace;

use crate::almanac::Almanac;
use crate::astro::Aberration;
use crate::context::Context;
use crate::errors::IntegrityErrorKind;
use crate::hifitime::Epoch;
use crate::math::units::*;
Expand All @@ -20,7 +20,7 @@ use crate::naif::daf::NAIFDataSet;
use crate::naif::spk::datatypes::{HermiteSetType13, LagrangeSetType9, Type2ChebyshevSet};
use crate::{errors::AniseError, prelude::Frame};

impl<'a> Context<'a> {
impl<'a> Almanac<'a> {
/// Returns the position vector and velocity vector of the `source` with respect to its parent in the ephemeris at the provided epoch,
/// and in the provided distance and time units.
///
Expand Down
4 changes: 2 additions & 2 deletions src/ephemerides/translations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
* Documentation: https://nyxspace.com/
*/

use crate::almanac::Almanac;
use crate::astro::Aberration;
use crate::context::Context;
use crate::hifitime::Epoch;
use crate::math::cartesian::CartesianState;
use crate::math::units::*;
Expand All @@ -22,7 +22,7 @@ use crate::{
/// **Limitation:** no translation or rotation may have more than 8 nodes.
pub const MAX_TREE_DEPTH: usize = 8;

impl<'a> Context<'a> {
impl<'a> Almanac<'a> {
/// Returns the position vector, velocity vector, and acceleration vector needed to translate the `from_frame` to the `to_frame`.
///
/// **WARNING:** This function only performs the translation and no rotation whatsoever. Use the `transform_from_to` function instead to include rotations.
Expand Down
4 changes: 4 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ pub enum AniseError {
exp: Semver,
},
DecodingError(der::Error),
IncompatibleRotation {
from: i32,
to: i32,
},
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
Expand Down
4 changes: 2 additions & 2 deletions src/frames/celestial_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Documentation: https://nyxspace.com/
*/

use crate::{context::Context, prelude::AniseError, NaifId};
use crate::{almanac::Almanac, prelude::AniseError, NaifId};

use super::{Frame, FrameTrait};
use core::fmt;
Expand Down Expand Up @@ -48,7 +48,7 @@ impl fmt::Display for CelestialFrame {
}
}

impl<'a> Context<'a> {
impl<'a> Almanac<'a> {
/// Tries to find the celestial frame data given the ephemeris center name and the orientation name.
/// # Note
/// The ephemeris name MUST match the name of the planetary constant.
Expand Down
4 changes: 2 additions & 2 deletions src/frames/geodetic_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

use super::{celestial_frame::CelestialFrame, CelestialFrameTrait, Frame, FrameTrait};
use crate::{
context::Context, prelude::AniseError, structure::planetocentric::ellipsoid::Ellipsoid, NaifId,
almanac::Almanac, prelude::AniseError, structure::planetocentric::ellipsoid::Ellipsoid, NaifId,
};
use core::fmt;

Expand Down Expand Up @@ -85,7 +85,7 @@ impl Into<Frame> for GeodeticFrame {
}
}

impl<'a> Context<'a> {
impl<'a> Almanac<'a> {
/// Tries to find the geodetic frame data given the ephemeris center name and the orientation name.
/// # Note
/// The ephemeris name MUST match the name of the planetary constant.
Expand Down
23 changes: 20 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ extern crate const_format;
extern crate hifitime;
extern crate log;

pub mod almanac;
pub mod astro;
pub mod cli;
pub mod constants;
pub mod context;
pub mod ephemerides;
pub mod errors;
pub mod frames;
Expand All @@ -29,8 +29,8 @@ pub mod time {
}

pub mod prelude {
pub use crate::almanac::Almanac;
pub use crate::astro::Aberration;
pub use crate::context::Context;
pub use crate::errors::AniseError;
pub use crate::frames::*;
pub use crate::math::units::*;
Expand All @@ -48,7 +48,7 @@ pub(crate) type NaifId = i32;

/// Memory maps a file and **copies** the data on the heap prior to returning a pointer to this heap data.
#[macro_export]
macro_rules! file_mmap {
macro_rules! file2heap {
($filename:tt) => {
match File::open($filename) {
Err(e) => Err(AniseError::IOError(e.kind())),
Expand All @@ -66,3 +66,20 @@ macro_rules! file_mmap {
}
};
}

/// Memory maps a file and **copies** the data on the heap prior to returning a pointer to this heap data.
#[macro_export]
macro_rules! file_mmap {
($filename:tt) => {
match File::open($filename) {
Err(e) => Err(AniseError::IOError(e.kind())),
Ok(file) => unsafe {
use memmap2::MmapOptions;
match MmapOptions::new().map(&file) {
Err(_) => Err(AniseError::IOUnknownError),
Ok(mmap) => Ok(mmap),
}
},
}
};
}
5 changes: 4 additions & 1 deletion src/math/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@

// Vector3 is nalgebra's Vector3 with a 64-bit floating point representation.
pub type Vector3 = nalgebra::Vector3<f64>;
pub type Vector4 = nalgebra::Vector4<f64>;
pub type Vector6 = nalgebra::Vector6<f64>;
pub type Matrix3 = nalgebra::Matrix3<f64>;
pub type Matrix6 = nalgebra::Matrix6<f64>;

pub mod angles;
pub mod cartesian;
pub mod interpolation;
pub mod polyfit;
pub mod rotation;
pub mod units;
pub mod utils;
// pub mod rotation;

/// Returns the projection of a onto b
pub fn projv(a: &Vector3, b: &Vector3) -> Vector3 {
Expand Down
Loading
Loading