Use generics instead of dyn
This commit is contained in:
parent
b72c601a25
commit
4c7540b524
|
@ -34,7 +34,7 @@ pub type PrinterVec = Vector3D<f64, PrinterUnits>;
|
|||
|
||||
/// Jog the gantry by pumping loads of gcode into the printer board
|
||||
pub async fn jog(gamepad: Arc<Gamepad>, mut printer: Printer) -> Never {
|
||||
printer.send_gcode(Box::new(G91Command)).await.unwrap();
|
||||
printer.send_gcode(G91Command).await.unwrap();
|
||||
println!("Sent G91Command");
|
||||
loop {
|
||||
let (setpoint_x, setpoint_y, setpoint_z) = gamepad.speed_setpoint();
|
||||
|
@ -57,7 +57,7 @@ pub async fn jog(gamepad: Arc<Gamepad>, mut printer: Printer) -> Never {
|
|||
velocity: velocity.into(),
|
||||
};
|
||||
printer
|
||||
.send_gcode(Box::new(command))
|
||||
.send_gcode(command)
|
||||
.await
|
||||
.expect("Failed to send movement command!");
|
||||
|
||||
|
|
|
@ -73,35 +73,32 @@ async fn write_to_spindle() -> Never {
|
|||
|
||||
async fn write_to_printer() -> Never {
|
||||
let mut printer = Printer::connect(DEFAULT_TTY).await.unwrap();
|
||||
printer.send_gcode(M114Command::new()).await.unwrap();
|
||||
printer
|
||||
.send_gcode(Box::new(M114Command::new()))
|
||||
.await
|
||||
.unwrap();
|
||||
printer
|
||||
.send_gcode(Box::new(G28Command::new(true, true, true)))
|
||||
.send_gcode(G28Command::new(true, true, true))
|
||||
.await
|
||||
.unwrap();
|
||||
loop {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
|
||||
printer
|
||||
.send_gcode(Box::new(G0Command {
|
||||
.send_gcode(G0Command {
|
||||
x: Some(50.0),
|
||||
y: Some(50.0),
|
||||
z: Some(5.0),
|
||||
e: None,
|
||||
velocity: None,
|
||||
}))
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
|
||||
printer
|
||||
.send_gcode(Box::new(G0Command {
|
||||
.send_gcode(G0Command {
|
||||
x: Some(25.0),
|
||||
y: Some(25.0),
|
||||
z: Some(5.0),
|
||||
e: None,
|
||||
velocity: None,
|
||||
}))
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ pub struct G0Command {
|
|||
}
|
||||
|
||||
impl GcodeCommand for G0Command {
|
||||
type Reply = ();
|
||||
fn command(&self) -> String {
|
||||
fn unpack(letter: &str, o: Option<f64>) -> String {
|
||||
o.map(|x| format!("{}{:.3}", letter, x)).unwrap_or_default()
|
||||
|
@ -25,9 +26,9 @@ impl GcodeCommand for G0Command {
|
|||
)
|
||||
}
|
||||
|
||||
fn parse_reply(&self, reply: &str) -> Result<GcodeReply> {
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply> {
|
||||
if reply.is_empty() {
|
||||
Ok(GcodeReply::NoReply)
|
||||
Ok(())
|
||||
} else {
|
||||
Err(GcodeReplyError {
|
||||
sent_command: self.command(),
|
||||
|
|
|
@ -19,6 +19,7 @@ impl G28Command {
|
|||
}
|
||||
|
||||
impl GcodeCommand for G28Command {
|
||||
type Reply = ();
|
||||
fn command(&self) -> String {
|
||||
let x = if self.home_x { "X" } else { "" };
|
||||
let y = if self.home_y { "Y" } else { "" };
|
||||
|
@ -26,7 +27,7 @@ impl GcodeCommand for G28Command {
|
|||
format!("G28 {} {} {}", x, y, z)
|
||||
}
|
||||
|
||||
fn parse_reply(&self, reply: &str) -> Result<GcodeReply> {
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply> {
|
||||
if !reply.is_empty() {
|
||||
Err(GcodeReplyError {
|
||||
sent_command: self.command(),
|
||||
|
@ -34,7 +35,7 @@ impl GcodeCommand for G28Command {
|
|||
problem: "Expected no reply".to_string(),
|
||||
})
|
||||
} else {
|
||||
Ok(GcodeReply::NoReply)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@ use super::*;
|
|||
pub struct G90Command;
|
||||
|
||||
impl GcodeCommand for G90Command {
|
||||
type Reply = ();
|
||||
fn command(&self) -> String {
|
||||
"G90".into()
|
||||
}
|
||||
|
||||
fn parse_reply(&self, reply: &str) -> Result<GcodeReply> {
|
||||
fn parse_reply(&self, reply: &str) -> Result<()> {
|
||||
if !reply.is_empty() {
|
||||
Err(GcodeReplyError {
|
||||
sent_command: self.command(),
|
||||
|
@ -17,7 +18,7 @@ impl GcodeCommand for G90Command {
|
|||
problem: "Expected no reply".to_string(),
|
||||
})
|
||||
} else {
|
||||
Ok(GcodeReply::NoReply)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@ use super::*;
|
|||
pub struct G91Command;
|
||||
|
||||
impl GcodeCommand for G91Command {
|
||||
type Reply = ();
|
||||
fn command(&self) -> String {
|
||||
"G91".into()
|
||||
}
|
||||
|
||||
fn parse_reply(&self, reply: &str) -> Result<GcodeReply> {
|
||||
fn parse_reply(&self, reply: &str) -> Result<()> {
|
||||
if !reply.is_empty() {
|
||||
Err(GcodeReplyError {
|
||||
sent_command: self.command(),
|
||||
|
@ -17,7 +18,7 @@ impl GcodeCommand for G91Command {
|
|||
problem: "Expected no reply".to_string(),
|
||||
})
|
||||
} else {
|
||||
Ok(GcodeReply::NoReply)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use crate::printer::PrinterPosition;
|
||||
|
||||
use super::*;
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
|
@ -13,12 +15,12 @@ impl M114Command {
|
|||
}
|
||||
|
||||
impl GcodeCommand for M114Command {
|
||||
type Reply = PrinterPosition;
|
||||
fn command(&self) -> String {
|
||||
"M114".into()
|
||||
}
|
||||
|
||||
// TODO: This one doesn't seem to work and throws an error
|
||||
fn parse_reply(&self, reply: &str) -> Result<GcodeReply> {
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply> {
|
||||
lazy_static! {
|
||||
static ref RE_SET: Vec<Regex> = vec![
|
||||
Regex::new(r"X:(\d+(?:\.\d+))").unwrap(),
|
||||
|
@ -42,11 +44,10 @@ impl GcodeCommand for M114Command {
|
|||
})
|
||||
.collect();
|
||||
|
||||
Ok(GcodeReply::M114Reply {
|
||||
Ok(PrinterPosition {
|
||||
x: fields[0].clone()?,
|
||||
y: fields[1].clone()?,
|
||||
z: fields[2].clone()?,
|
||||
e: fields[3].clone()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@ use super::*;
|
|||
pub struct M997Command;
|
||||
|
||||
impl GcodeCommand for M997Command {
|
||||
type Reply = ();
|
||||
fn command(&self) -> String {
|
||||
"M997".into()
|
||||
}
|
||||
|
||||
fn parse_reply(&self, reply: &str) -> Result<GcodeReply> {
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply> {
|
||||
if !reply.is_empty() {
|
||||
Err(GcodeReplyError {
|
||||
sent_command: self.command(),
|
||||
|
@ -17,7 +18,7 @@ impl GcodeCommand for M997Command {
|
|||
problem: "Expected no reply".to_string(),
|
||||
})
|
||||
} else {
|
||||
Ok(GcodeReply::NoReply)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ impl std::fmt::Display for GcodeReplyError {
|
|||
}
|
||||
|
||||
pub trait GcodeCommand: Debug + Send {
|
||||
type Reply;
|
||||
fn command(&self) -> String;
|
||||
fn parse_reply(&self, reply: &str) -> Result<GcodeReply>;
|
||||
fn parse_reply(&self, reply: &str) -> Result<Self::Reply>;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,12 @@ pub enum PrinterError {
|
|||
NoResponseFromPrinter(String),
|
||||
}
|
||||
|
||||
pub struct PrinterPosition {
|
||||
x: f64,
|
||||
y: f64,
|
||||
z: f64,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
position: (f64, f64, f64, f64),
|
||||
}
|
||||
|
@ -48,10 +54,10 @@ pub struct Printer {
|
|||
|
||||
impl Printer {
|
||||
/// Send gcode to the printer and parse its reply
|
||||
pub async fn send_gcode(
|
||||
pub async fn send_gcode<T: GcodeCommand>(
|
||||
&mut self,
|
||||
command: Box<dyn GcodeCommand>,
|
||||
) -> Result<GcodeReply, PrinterError> {
|
||||
command: T,
|
||||
) -> Result<T::Reply, PrinterError> {
|
||||
let command_text = format!("{}\n", command.command());
|
||||
self.serial_tx.send(command_text.clone()).await.unwrap();
|
||||
let mut reply = String::with_capacity(RECV_BUFFER_CAPACITY);
|
||||
|
@ -127,7 +133,7 @@ impl Printer {
|
|||
maximum_buffer_capacity: 0, // this is updated on the next call to `send_gcode()`
|
||||
};
|
||||
|
||||
res.send_gcode(Box::new(G91Command))
|
||||
res.send_gcode(G91Command)
|
||||
.await
|
||||
.expect("Could not ask for current position!");
|
||||
|
||||
|
|
Loading…
Reference in a new issue