use super::*;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Command {
Position(f32),
Velocity(f32),
Acceleration(f32),
}
impl Command {
pub const fn new(position_derivative: PositionDerivative, value: f32) -> Self {
match position_derivative {
PositionDerivative::Position => Self::Position(value),
PositionDerivative::Velocity => Self::Velocity(value),
PositionDerivative::Acceleration => Self::Acceleration(value),
}
}
pub fn get_position(&self) -> Option<Quantity> {
match self {
Self::Position(pos) => Some(Quantity::new(*pos, MILLIMETER)),
_ => None,
}
}
pub fn get_velocity(&self) -> Option<Quantity> {
match self {
Self::Position(_) => Some(Quantity::new(0.0, MILLIMETER_PER_SECOND)),
Self::Velocity(vel) => Some(Quantity::new(*vel, MILLIMETER_PER_SECOND)),
Self::Acceleration(_) => None,
}
}
pub fn get_acceleration(&self) -> Quantity {
Quantity::new(
match self {
Self::Acceleration(acc) => *acc,
_ => 0.0,
},
MILLIMETER_PER_SECOND_SQUARED,
)
}
}
impl From<State> for Command {
fn from(state: State) -> Self {
if state.acceleration == 0.0 {
if state.velocity == 0.0 {
return Command::new(PositionDerivative::Position, state.position);
} else {
return Command::new(PositionDerivative::Velocity, state.velocity);
}
} else {
return Command::new(PositionDerivative::Acceleration, state.acceleration);
}
}
}
#[cfg(any(
feature = "dim_check_release",
all(debug_assertions, feature = "dim_check_debug")
))]
impl TryFrom<Quantity> for Command {
type Error = ();
fn try_from(was: Quantity) -> Result<Self, ()> {
match was.unit {
MILLIMETER => Ok(Self::Position(was.value)),
MILLIMETER_PER_SECOND => Ok(Self::Velocity(was.value)),
MILLIMETER_PER_SECOND_SQUARED => Ok(Self::Acceleration(was.value)),
_ => Err(()),
}
}
}
impl From<Command> for f32 {
fn from(was: Command) -> f32 {
match was {
Command::Position(pos) => pos,
Command::Velocity(vel) => vel,
Command::Acceleration(acc) => acc,
}
}
}
impl Add for Command {
type Output = Self;
fn add(self, rhs: Self) -> Self {
let self_pos_der = PositionDerivative::from(self);
assert_eq!(self_pos_der, PositionDerivative::from(rhs));
Self::new(self_pos_der, f32::from(self) + f32::from(rhs))
}
}
impl Sub for Command {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
let self_pos_der = PositionDerivative::from(self);
assert_eq!(self_pos_der, PositionDerivative::from(rhs));
Self::new(self_pos_der, f32::from(self) - f32::from(rhs))
}
}
impl Mul<f32> for Command {
type Output = Self;
fn mul(self, rhs: f32) -> Self {
let self_pos_der = PositionDerivative::from(self);
let value = f32::from(self) * rhs;
Self::new(self_pos_der, value)
}
}
impl Div<f32> for Command {
type Output = Self;
fn div(self, rhs: f32) -> Self {
let self_pos_der = PositionDerivative::from(self);
let value = f32::from(self) / rhs;
Self::new(self_pos_der, value)
}
}
impl Neg for Command {
type Output = Self;
fn neg(self) -> Self {
match self {
Self::Position(pos) => Self::Position(-pos),
Self::Velocity(vel) => Self::Velocity(-vel),
Self::Acceleration(acc) => Self::Acceleration(-acc),
}
}
}
impl AddAssign for Command {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
impl SubAssign for Command {
fn sub_assign(&mut self, rhs: Self) {
*self = *self - rhs;
}
}
impl MulAssign<f32> for Command {
fn mul_assign(&mut self, rhs: f32) {
*self = *self * rhs;
}
}
impl DivAssign<f32> for Command {
fn div_assign(&mut self, rhs: f32) {
*self = *self / rhs;
}
}