use serde::{Serialize, Deserialize};
use crate::{SyncActuator, Setup, Stepper};
use crate::act::LinearAxis;
use crate::act::stepper::StepperActuator;
use crate::data::StepperConfig;
use syunit::*;
pub type StepperCylTriangle = CylinderTriangle<Stepper>;
#[derive(Debug, Serialize, Deserialize)]
pub struct CylinderTriangle<C : SyncActuator> {
pub cylinder : LinearAxis<C>,
pub l_a : f32,
pub l_b : f32,
}
impl<C : SyncActuator> CylinderTriangle<C> {
pub fn new(cylinder : LinearAxis<C>, l_a : f32, l_b : f32) -> Self {
let mut tri = CylinderTriangle {
l_a,
l_b,
cylinder
};
tri.cylinder.set_gamma(Gamma(l_a.max(l_b)));
return tri;
}
pub fn alpha_for_gam(&self, gam : Gamma) -> f32 {
(self.l_a / self.gamma_for_parent(gam).0 * gam.sin()).asin()
}
pub fn beta_for_gam(&self, gam : Gamma) -> f32 {
(self.l_b / self.gamma_for_parent(gam).0 * gam.sin()).asin()
}
pub fn omega_for_gam(&self, omega : Velocity, gam : Gamma) -> Velocity {
omega / self.l_a * self.beta_for_gam(gam).sin()
}
pub fn vel_for_gam(&self, omega : Velocity, gam : Gamma) -> Velocity {
omega * self.l_a / self.beta_for_gam(gam).sin()
}
}
impl<C : SyncActuator> Setup for CylinderTriangle<C> {
fn setup(&mut self) -> Result<(), crate::Error> {
self.cylinder.setup()?;
self.cylinder.set_gamma(Gamma(self.l_a.max(self.l_b)));
Ok(())
}
}
impl<C : SyncActuator> SyncActuator for CylinderTriangle<C> {
fn data<'a>(&'a self) -> &'a crate::data::StepperConfig {
self.cylinder.data()
}
fn vars<'a>(&'a self) -> &'a crate::data::ActuatorVars {
self.cylinder.vars()
}
fn child(&self) -> Option<&dyn SyncActuator> {
Some(&self.cylinder)
}
fn child_mut(&mut self) -> Option<&mut dyn SyncActuator> {
Some(&mut self.cylinder)
}
fn gamma_for_parent(&self, gam : Gamma) -> Gamma {
Gamma((self.l_a.powi(2) + self.l_b.powi(2) - 2.0 * self.l_a * self.l_b * gam.0.cos()).powf(0.5))
}
fn gamma_for_this(&self, len : Gamma) -> Gamma {
Gamma(((self.l_a.powi(2) + self.l_b.powi(2) - len.0.powi(2)) / 2.0 / self.l_a / self.l_b).acos())
}
fn omega_for_this(&self, parent_omega : Velocity, this_gamma : Gamma) -> Velocity {
parent_omega / self.l_a * self.beta_for_gam(this_gamma).sin()
}
fn set_config(&mut self, data : StepperConfig) {
self.cylinder.set_config(data);
}
fn omega_max(&self) -> Velocity {
self.cylinder.omega_max()
}
fn set_velocity_max(&mut self, omega_max : Velocity) {
self.cylinder.set_velocity_max(omega_max)
}
fn drive_rel(&mut self, mut delta : Delta, speed_f : f32) -> Result<Delta, crate::Error> {
let gamma = self.gamma();
delta = self.delta_for_parent(delta, gamma);
delta = self.cylinder.drive_rel(delta, speed_f)?;
Ok(self.delta_for_this(delta, self.gamma_for_parent(gamma)))
}
fn apply_gen_force(&mut self, force : Force) -> Result<(), crate::Error> {
self.cylinder.apply_gen_force(force)
}
fn apply_inertia(&mut self, inertia : Inertia) {
self.cylinder.apply_inertia(inertia)
}
}
impl<C : StepperActuator> StepperActuator for CylinderTriangle<C> {
#[inline]
fn parent_stepper_comp(&self) -> Option<&dyn StepperActuator> {
Some(&self.cylinder)
}
#[inline]
fn parent_stepper_comp_mut(&mut self) -> Option<&mut dyn StepperActuator> {
Some(&mut self.cylinder)
}
#[inline]
fn motor(&self) -> &dyn crate::prelude::StepperMotor {
self.cylinder.motor()
}
#[inline]
fn motor_mut(&mut self) -> &mut dyn crate::prelude::StepperMotor {
self.cylinder.motor_mut()
}
}