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