parent
d041febfdc
commit
125d1facf7
@ -0,0 +1,124 @@
|
||||
use std::io::{self, Write};
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum Direction {
|
||||
Clockwise,
|
||||
AntiClockwise,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Tool {
|
||||
Off,
|
||||
On,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum Distance {
|
||||
Absolute,
|
||||
Incremental,
|
||||
}
|
||||
|
||||
pub type Program = Vec<GCode>;
|
||||
|
||||
macro_rules! write_if_some {
|
||||
($w:expr, $s:expr, $v:ident) => {
|
||||
if let Some(v) = $v {
|
||||
write!($w, $s, v)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum GCode {
|
||||
RapidPositioning {
|
||||
x: Option<f64>,
|
||||
y: Option<f64>,
|
||||
},
|
||||
LinearInterpolation {
|
||||
x: Option<f64>,
|
||||
y: Option<f64>,
|
||||
z: Option<f64>,
|
||||
f: Option<f64>,
|
||||
},
|
||||
Dwell {
|
||||
p: f64,
|
||||
},
|
||||
UnitsInches,
|
||||
UnitsMillimeters,
|
||||
ProgramEnd,
|
||||
StartSpindle {
|
||||
d: Direction,
|
||||
s: f64,
|
||||
},
|
||||
StopSpindle,
|
||||
DistanceMode(Distance),
|
||||
Named(Box<String>),
|
||||
}
|
||||
|
||||
pub fn program2gcode<W: Write>(p: &Program, mut w: W) -> io::Result<()> {
|
||||
use GCode::*;
|
||||
for code in p.iter() {
|
||||
match code {
|
||||
RapidPositioning { x, y } => {
|
||||
if let (None, None) = (x, y) {
|
||||
continue;
|
||||
}
|
||||
write!(w, "G0")?;
|
||||
write_if_some!(w, " X{}", x)?;
|
||||
write_if_some!(w, " Y{}", y)?;
|
||||
writeln!(w)?;
|
||||
}
|
||||
LinearInterpolation { x, y, z, f } => {
|
||||
if let (None, None, None, None) = (x, y, z, f) {
|
||||
continue;
|
||||
}
|
||||
write!(w, "G1")?;
|
||||
write_if_some!(w, " X{}", x)?;
|
||||
write_if_some!(w, " Y{}", y)?;
|
||||
write_if_some!(w, " Z{}", z)?;
|
||||
write_if_some!(w, " F{}", f)?;
|
||||
writeln!(w)?;
|
||||
}
|
||||
Dwell { p } => {
|
||||
writeln!(w, "G4 P{}", p)?;
|
||||
}
|
||||
UnitsInches => {
|
||||
writeln!(w, "G20")?;
|
||||
}
|
||||
UnitsMillimeters => {
|
||||
writeln!(w, "G21")?;
|
||||
}
|
||||
ProgramEnd => {
|
||||
writeln!(w, "M20")?;
|
||||
}
|
||||
StartSpindle { d, s } => {
|
||||
let d = match d {
|
||||
Direction::Clockwise => 3,
|
||||
Direction::AntiClockwise => 4,
|
||||
};
|
||||
writeln!(w, "M{} S{}", d, s)?;
|
||||
}
|
||||
StopSpindle => {
|
||||
writeln!(w, "M5")?;
|
||||
}
|
||||
DistanceMode(mode) => {
|
||||
writeln!(
|
||||
w,
|
||||
"G{}",
|
||||
match mode {
|
||||
Distance::Absolute => 90,
|
||||
Distance::Incremental => 91,
|
||||
}
|
||||
)?;
|
||||
}
|
||||
Named(name) => {
|
||||
if name.len() > 0 {
|
||||
writeln!(w, "({})", name)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
use super::code::*;
|
||||
|
||||
pub struct Machine {
|
||||
tool_state: Tool,
|
||||
distance_mode: Distance,
|
||||
pub tool_on_action: Program,
|
||||
pub tool_off_action: Program,
|
||||
}
|
||||
|
||||
impl Default for Machine {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
tool_state: Tool::Off,
|
||||
distance_mode: Distance::Absolute,
|
||||
tool_on_action: vec![],
|
||||
tool_off_action: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub fn tool_on(&mut self, p: &mut Program) {
|
||||
if self.tool_state == Tool::Off {
|
||||
self.tool_on_action
|
||||
.iter()
|
||||
.map(Clone::clone)
|
||||
.for_each(|x| p.push(x));
|
||||
}
|
||||
self.tool_state = Tool::On;
|
||||
}
|
||||
|
||||
pub fn tool_off(&mut self, p: &mut Program) {
|
||||
if self.tool_state == Tool::On {
|
||||
self.tool_off_action
|
||||
.iter()
|
||||
.map(Clone::clone)
|
||||
.for_each(|x| p.push(x));
|
||||
}
|
||||
self.tool_state = Tool::Off;
|
||||
}
|
||||
|
||||
pub fn distance(&mut self, p: &mut Program, is_absolute: bool) {
|
||||
if is_absolute {
|
||||
self.absolute(p);
|
||||
} else {
|
||||
self.incremental(p);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn absolute(&mut self, p: &mut Program) {
|
||||
if self.distance_mode == Distance::Incremental {
|
||||
p.push(GCode::DistanceMode(Distance::Absolute));
|
||||
}
|
||||
self.distance_mode = Distance::Absolute;
|
||||
}
|
||||
|
||||
pub fn incremental(&mut self, p: &mut Program) {
|
||||
if self.distance_mode == Distance::Absolute {
|
||||
p.push(GCode::DistanceMode(Distance::Incremental));
|
||||
}
|
||||
self.distance_mode = Distance::Incremental;
|
||||
}
|
||||
}
|
Loading…
Reference in new issue