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