use crate::fb::StateMachine;
use super::axis_view::AxisHandle;
#[derive(Debug, Clone)]
pub struct MoveToLoad {
pub done: bool,
pub active: bool,
pub error: bool,
pub state: StateMachine,
moving_negative: bool,
}
impl Default for MoveToLoad {
fn default() -> Self {
Self {
done: false,
active: false,
error: false,
state: StateMachine::new(),
moving_negative: false,
}
}
}
impl MoveToLoad {
pub fn new() -> Self {
Self::default()
}
pub fn abort(&mut self, axis: &mut impl AxisHandle) {
axis.halt();
self.error = true;
self.active = false;
self.state.set_error(1, "Abort called");
self.state.index = 100;
}
pub fn call(
&mut self,
axis: &mut impl AxisHandle,
execute: bool,
target_load: f64,
current_load: f64,
position_limit: f64,
hysteresis: f64,
) {
let hyst = hysteresis.max(1.0);
if !execute {
if self.active {
axis.halt();
}
self.done = false;
self.active = false;
self.error = false;
self.state.index = 0;
return;
}
if axis.is_error() && self.state.index != 100 {
self.error = true;
self.active = false;
self.state.set_error(120, "Axis is in error state");
self.state.index = 100;
}
match self.state.index {
0 => { self.done = false;
self.error = false;
self.active = true;
self.state.clear_error();
self.moving_negative = current_load > target_load;
let reached = if self.moving_negative {
current_load <= target_load + hyst
} else {
current_load >= target_load - hyst
};
if reached {
self.done = true;
self.active = false;
self.state.index = 30;
} else {
if (self.moving_negative && axis.position() <= position_limit) ||
(!self.moving_negative && axis.position() >= position_limit) {
self.error = true;
self.active = false;
self.state.set_error(110, "Axis already past position limit before starting");
self.state.index = 100;
} else {
let vel = axis.config().jog_speed;
let acc = axis.config().jog_accel;
let dec = axis.config().jog_decel;
axis.move_absolute(position_limit, vel, acc, dec);
self.state.index = 10;
}
}
}
10 => { let reached = if self.moving_negative {
current_load <= target_load + hyst
} else {
current_load >= target_load - hyst
};
if reached {
axis.halt();
self.state.index = 20; } else {
let hit_limit = if self.moving_negative {
axis.position() <= position_limit + 0.0001
} else {
axis.position() >= position_limit - 0.0001
};
if hit_limit || !axis.is_busy() {
axis.halt();
self.error = true;
self.active = false;
self.state.set_error(150, "Reached position limit without hitting target load");
self.state.index = 100;
}
}
}
20 => { if !axis.is_busy() {
self.done = true;
self.active = false;
self.state.index = 30;
}
}
30 => { }
100 => { }
_ => {
self.state.index = 0;
}
}
self.state.call();
}
}