Skip to content

Commit

Permalink
Productive co-engineering session!
Browse files Browse the repository at this point in the history
Co-authored-by: Chris de Claverie <c.de-claverie@protonmail.com>
Co-authored-by: Grégoire Henry <greg.henry@mail.com>
Signed-off-by: Christopher Rabotin <christopher.rabotin@gmail.com>
  • Loading branch information
3 people committed Nov 6, 2022
1 parent 870695f commit 04b719f
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/context/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl<'a> AniseContext<'a> {
/// # Potential errors
/// + The resulting file would have too many trajectories compared to the maximum number of trajectories
/// + Two trajectories have the same name but different contents
/// + Incomatible versions: the versions of self and other must match
/// + Incompatible versions: the versions of self and other must match
pub fn merge_mut(&mut self, other: &'a Self) -> Result<(usize, usize), AniseError> {
// Check the versions match (eventually, we need to make sure that the versions are compatible)
if self.metadata.anise_version != other.metadata.anise_version {
Expand Down
1 change: 1 addition & 0 deletions src/math/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub type Vector6 = nalgebra::Vector6<f64>;
pub mod angles;
pub mod cartesian;
pub mod interpolation;
pub mod rotation;

/// Returns the projection of a onto b
pub fn projv(a: &Vector3, b: &Vector3) -> Vector3 {
Expand Down
149 changes: 149 additions & 0 deletions src/math/rotation/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use nalgebra::Vector3;

pub trait Rotation<T> {
// What do we want as a common interface for rotations?

// My suggestion :
fn new(axis: Vector3<T>, angle: T) -> Self;
fn axis(&self) -> Vector3<T>;
fn angle(&self) -> T; // Rotation angle in radians around the rotation axis

//fn compose<T2, Rot2<T2> where Rot2<T2> : !ComposeWith<Rot<T>>>(&self, other: &Rot2<T>) -> (Vector3<T>, T) {
// Composition of two rotations with possibly differing precision

// Imo the best approach would be to have two implementations
// A specific one, for example composition of two quaternions is a multiplication that can be made very efficient
// And a generic one that would be the conversion into axis/angle of both rotations and then compose the axis/angle representations
// This could probably be implemented with smart usage of a ComposeWith trait

// Reference for the generic approach : https://math.stackexchange.com/questions/382760/composition-of-two-axis-angle-rotations
// We should probably get the formulas through Herbie floating point optimization

// let alpha = self.angle(); let beta = other.angle(); let l = self.axis(); let m = other.axis();
// let new_angle = 2*acos(cos(alpha/2) * cos(beta/2) - l.dot(m) * sin(alpha/2) * sin(beta/2));
// let new_axis = (2/new_angle)*asin( sin(alpha/2) * cos(beta/2) * l + cos(alpha/2) * sin(beta/2) * m + sin(alpha/2) * sin(beta/2) * l.cross(m) );

// Will automatically be coerced into a RawRotation via the From trait, if needed
// (new_axis, new_angle)
// }

// fn inverse(&self) -> Self ?
}

pub trait ComposeWith<T> {
type Output;

fn compose(&self, other: &T) -> Self::Output;
}

// Possible tests for all rotations :
// Check transformation is correct : rotation -> RawRotation -> rotation
// Check composition rules are correct with inverse rotation ?
// Check edge cases : all-zero axis, non-unit axis, zero angle, , NaN/Inf angle, angle > PI or < PI, others ?
// Check against other libraries ?
// Check performance differences ?

/// Raw rotation, represented as an axis and angle
pub struct RawRotation<T> {
pub axis: Vector3<T>,
pub angle: T,
}

impl<T: Clone> Rotation<T> for RawRotation<T> {
fn new(axis: Vector3<T>, angle: T) -> Self {
Self { axis, angle }
}

fn axis(&self) -> Vector3<T> {
self.axis.clone()
}

fn angle(&self) -> T {
self.angle.clone()
}
}

impl<T: Clone> From<(Vector3<T>, T)> for RawRotation<T> {
fn from((axis, angle): (Vector3<T>, T)) -> Self {
Self::new(axis, angle)
}
}

/// Unit quaternion with a specified tolerance for normalization
pub struct RotQuaternion<T> {
pub w: T,
pub x: T,
pub y: T,
pub z: T,

/// Tolerances are used in the normalization process to make sure
/// that the quaternion is normalized with the needed guarantees
// Should tolerances be optional ? I'd say they should be mandatory but have a fair default value
pub abs_tolerance: T,
pub rel_tolerance: T,
//// Source and destination reference frames are used for runtime check of
//// the correctness of the rotation
// TODO : we should have a way to disable runtime checks
// pub source : RefFrameHash,
// pub destination : RefFrameHash
}

impl<T: core::convert::From<f32>> RotQuaternion<T> {
pub fn new(w: T, x: T, y: T, z: T) -> Self {
// TODO : Check the quaternion is unitary with the correct tolerance
todo!();

Self {
w,
x,
y,
z,
abs_tolerance: T::from(1e-6_f32),
rel_tolerance: T::from(1e-6_f32),
}
}
}

impl<T> RotQuaternion<T> {
pub fn new_with_tol(w: T, x: T, y: T, z: T, abs_tol: T, rel_tol: T) -> Self {
// TODO : Check the quaternion is unit with the correct tolerance
todo!();

Self {
w,
x,
y,
z,
abs_tolerance: abs_tol,
rel_tolerance: rel_tol,
}
}
}

impl<T> Rotation<T> for RotQuaternion<T> {
fn new(axis: Vector3<T>, angle: T) -> Self {
todo!();
}
fn axis(&self) -> Vector3<T> {
todo!()
}

fn angle(&self) -> T {
todo!()
}
}

impl<T> ComposeWith<RotQuaternion<T>> for RotQuaternion<T> {
// TODO : allow differing precisions ?
type Output = Self;

fn compose(&self, other: &Self) -> Self::Output {
todo!()
}
}

/// Modified Rodrigues parameter
pub struct MRP {}

// etc... :)
// Good night !
5 changes: 3 additions & 2 deletions src/structure/spline/splines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::meta::SplineMeta;

// #[derive(Enumerated)]
// #[repr(u8)]
// pub enum TrunctationStrategy {
// pub enum TruncationStrategy {
// None = 0,
// TruncateLow = 1,
// TruncateHigh = 2,
Expand All @@ -27,8 +27,9 @@ use super::meta::SplineMeta;
pub struct Splines<'a> {
/// Metadata of the spline
pub metadata: SplineMeta,
// use AsBytes / FromBytes from "zerocopy" crate to load the data ?
/// Stores the CRC32 checksum of the data octet string.
pub data_checksum: u32,
pub data_checksum: u32, // TODO: move the checksum into a CRC32DataArray to check integrity on load
/// The data as a packed struct of octets
pub data: &'a [u8],
}
Expand Down

0 comments on commit 04b719f

Please sign in to comment.