use crate::buffer_fifo::BufferFIFO;
use crate::motion_polynomial::MotionPolynomial;
pub struct MotionPolynomialExecutor<const N: usize> {
buffer: BufferFIFO<MotionPolynomial, N>,
init: MotionPolynomial,
inst: MotionPolynomial,
freq: f64,
time: i32,
duration: i32,
}
impl<const N: usize> MotionPolynomialExecutor<N> {
pub fn new(freq: u16) -> Self {
Self {
freq: freq as f64,
time: 1,
duration: 0,
buffer: BufferFIFO::default(),
init: MotionPolynomial::default(),
inst: MotionPolynomial::default(),
}
}
pub fn add_task(&mut self, task: MotionPolynomial) {
self.buffer.write(task);
}
fn get_next(&mut self) {
if !self.buffer.is_empty() {
let new_task = self.buffer.read();
if new_task.time != 0.0 {
self.init = new_task;
self.inst = new_task;
self.inst.time = 0.0;
self.duration = (new_task.time * self.freq) as i32;
self.time = 0;
} else {
self.get_next();
}
}
}
fn math(&mut self) {
let j0 = self.init.jrk;
let a0 = self.init.acc;
let v0 = self.init.vel;
let s0 = self.init.pos;
let time = self.time as f64 / self.freq;
let acc = a0 + j0 * time;
let vel = v0 + (a0 + acc) * time * 0.5;
let vel_avg = v0 + (2.0 * a0 + acc) * time / 6.0;
let pos = s0 + vel_avg * time;
self.inst.acc = acc;
self.inst.vel = vel;
self.inst.pos = pos;
self.inst.time = time;
}
pub fn tick(&mut self) {
if self.time > self.duration {
self.get_next();
} else {
self.time += 1;
self.math();
}
}
pub fn set_freq(&mut self, freq: i16) {
self.freq = freq as f64;
}
pub fn get_acc(&self) -> f64 {
self.inst.acc
}
pub fn get_vel(&self) -> f64 {
self.inst.vel
}
pub fn get_pos(&self) -> f64 {
self.inst.pos
}
pub fn is_full(&self) -> bool {
self.buffer.is_full()
}
}