use syunit::*;
pub const ROOT_EPSILON : f32 = -1.0e-4;
pub mod time {
use super::*;
pub fn from_omega_start_end(omega_0 : Velocity, omega : Velocity, delta : Delta) -> Time {
2.0 * delta / (omega_0 + omega)
}
#[inline]
pub fn positive_travel_time(delta : Delta, omega : Velocity, alpha : Acceleration) -> Option<Time> {
let (mut t_1, mut t_2) = travel_times(delta, omega, alpha);
if t_1.is_sign_negative() {
t_1 = Time::INFINITY;
if t_2.is_sign_negative() {
return None; }
} else if t_2.is_sign_negative() {
t_2 = Time::INFINITY; }
Some(t_1.min(t_2))
}
}
pub mod delta {
use super::*;
#[inline]
pub fn from_omega_start_end(omega_0 : Velocity, omega : Velocity, time : Time) -> Delta {
(omega_0 + omega) / 2.0 * time
}
#[inline]
pub fn from_omega_alpha(omega_0 : Velocity, alpha : Acceleration, time : Time) -> Delta {
omega_0 * time + alpha * time * time / 2.0
}
}
pub mod velocity {
use super::*;
pub fn from_delta_time_0(omega_0 : Velocity, delta : Delta, time : Time) -> Velocity {
2.0 * delta / time - omega_0
}
}
#[inline]
pub fn travel_times(delta : Delta, omega : Velocity, alpha : Acceleration) -> (Time, Time) {
if !alpha.is_normal() {
panic!("The given alpha is invalid (delta: {}, omega: {}, alpha: {})", delta, omega, alpha);
}
let p = omega / alpha;
let q = 2.0 * delta.0 / alpha.0;
let inner = p.0.powi(2) + q;
let mut root = Time(inner.sqrt());
if inner.is_sign_negative() & (inner > ROOT_EPSILON) {
root = Time::ZERO;
}
( -p + root, -p - root )
}
pub fn accel_from_zero(delta : Delta, alpha : Acceleration) -> Time {
Time((2.0 * delta.0 / alpha.0).sqrt())
}
pub fn alpha_req_for_dist(delta : Delta, omega : Velocity) -> Acceleration {
Acceleration(omega.0 * omega.0 / 2.0 / delta.0)
}
pub fn omega_start_stop(force_stall : Force, inertia : Inertia, number_of_steps : u64) -> Velocity {
Velocity((force_stall.0 / inertia.0 * core::f32::consts::PI / number_of_steps as f32).sqrt())
}