diff --git a/hostcontrol/src/gcode_stage.rs b/hostcontrol/src/gcode_stage.rs new file mode 100644 index 0000000..28d5250 --- /dev/null +++ b/hostcontrol/src/gcode_stage.rs @@ -0,0 +1,45 @@ +use crate::stage_io::StageIO; +use crate::xy_stage::{Result, XYStage}; + +pub struct GCodeStage { + stage_io: StageIO, + max_range_μm: nalgebra::Vector3, +} + +impl GCodeStage { + pub fn new(stage_io: StageIO) -> Result { + let mut res = Self { + stage_io, + // TODO: determine max range with some M-code ? + max_range_μm: nalgebra::vector![100.0 * 1000.0, 100.0 * 1000.0, 50.0 * 1000.0], + }; + res.stage_io.send_request("G28\n")?; + Ok(res) + } +} + +impl XYStage for GCodeStage { + /// Move to absolute coordinates (x,y,z) in micrometers. + fn move_absolute_cartesian(&mut self, a: nalgebra::Vector3) -> Result<()> { + // TODO: check range + self.stage_io.send_request(format!( + "G1 X{} Y{} Z{}\n", + a[0] / 1000.0, + a[1] / 1000.0, + a[2] / 1000.0 + ))?; + Ok(()) + } + + /// Get range of valid cartesian coordinates box. For now, assuming one + /// corner is fixed at (0,0,0), the other remote corner is this range. + fn get_range(&self) -> nalgebra::Vector3 { + self.max_range_μm + } +} + +impl Drop for GCodeStage { + fn drop(&mut self) { + self.stage_io.send_request("M84\n").unwrap(); // switch off motors. + } +} diff --git a/hostcontrol/src/main.rs b/hostcontrol/src/main.rs index 4004786..a3f97a8 100644 --- a/hostcontrol/src/main.rs +++ b/hostcontrol/src/main.rs @@ -1,6 +1,7 @@ -use clap::Parser; +use clap::{Parser, ValueEnum}; use std::{thread::sleep, time::Duration}; +mod gcode_stage; mod openflexure_stage; mod stage_io; @@ -19,19 +20,37 @@ struct CliArgs { /// Speed of the stage device (bps) #[arg(long, default_value = "115200")] tty_speed: u32, + + #[arg(long, value_enum)] + backend: Backend, +} + +// [derive(DebugCopy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +#[derive(Debug, Clone, ValueEnum)] +enum Backend { + /// OpenFlexure stage + OpenFlexure, + + /// GCode stage + GCode, } fn main() { let args = CliArgs::parse(); env_logger::init(); let stage_io = StageIO::new(&args.stage_device, args.tty_speed).unwrap(); - let mut s = openflexure_stage::OpenFlexureStage::new(stage_io, 1.12).unwrap(); + let mut stage: Box = match args.backend { + Backend::GCode => Box::new(gcode_stage::GCodeStage::new(stage_io).unwrap()), + Backend::OpenFlexure => { + Box::new(openflexure_stage::OpenFlexureStage::new(stage_io, 1.12).unwrap()) + } + }; let origin = nalgebra::vector![0.0, 0.0, 0.0]; - s.move_absolute_cartesian(origin).unwrap(); + stage.move_absolute_cartesian(origin).unwrap(); sleep(Duration::from_secs(1)); - let mut max_xy = s.get_range(); + let mut max_xy = stage.get_range(); max_xy[2] = 0.0; - s.move_absolute_cartesian(max_xy).unwrap(); + stage.move_absolute_cartesian(max_xy).unwrap(); sleep(Duration::from_secs(5)); } diff --git a/hostcontrol/src/openflexure_stage.rs b/hostcontrol/src/openflexure_stage.rs index d5b3ddc..2c98cda 100644 --- a/hostcontrol/src/openflexure_stage.rs +++ b/hostcontrol/src/openflexure_stage.rs @@ -1,7 +1,7 @@ //! Stage controller for openflexure-delta like stage controllers. use crate::stage_io::StageIO; -use crate::xy_stage::{XYStage, StageError,Result}; +use crate::xy_stage::{Result, StageError, XYStage}; fn new_camera_rotation(theta: f64) -> nalgebra::Matrix3 { nalgebra::matrix![ @@ -93,7 +93,7 @@ impl OpenFlexureStage { impl XYStage for OpenFlexureStage { fn move_absolute_cartesian(&mut self, a: nalgebra::Vector3) -> Result<()> { - // TODO: check range with get_movement_box() + // TODO: check range with get_movement_box() let current = self.get_position_delta(); let target = self.cartesian_to_delta * a; let target = nalgebra::vector![target[0] as i32, target[1] as i32, target[2] as i32]; @@ -114,6 +114,6 @@ impl XYStage for OpenFlexureStage { } fn get_range(&self) -> nalgebra::Vector3 { - nalgebra::vector![10000.0, 10000.0, 5000.0] + nalgebra::vector![10000.0, 10000.0, 5000.0] } } diff --git a/hostcontrol/src/xy_stage.rs b/hostcontrol/src/xy_stage.rs index 8a22179..1f645c3 100644 --- a/hostcontrol/src/xy_stage.rs +++ b/hostcontrol/src/xy_stage.rs @@ -1,4 +1,3 @@ - use crate::stage_io::StageIOError; use thiserror::Error;