From cc8152a75df0ec7614d3fd4a7618d30c826ce596 Mon Sep 17 00:00:00 2001 From: Henner Zeller Date: Sun, 8 Mar 2026 12:48:39 +0100 Subject: [PATCH] Break out stage IO into separate file. Signed-off-by: Henner Zeller --- hostcontrol/src/main.rs | 5 +++- hostcontrol/src/stage.rs | 54 +---------------------------------- hostcontrol/src/stage_io.rs | 56 +++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 54 deletions(-) create mode 100644 hostcontrol/src/stage_io.rs diff --git a/hostcontrol/src/main.rs b/hostcontrol/src/main.rs index 7d525f5..4b98db6 100644 --- a/hostcontrol/src/main.rs +++ b/hostcontrol/src/main.rs @@ -3,6 +3,9 @@ use std::{thread::sleep, time::Duration}; mod stage; +mod stage_io; +use crate::stage_io::StageIO; + #[derive(clap::Parser, Debug)] #[command(version, about, long_about = None)] struct CliArgs { @@ -18,7 +21,7 @@ struct CliArgs { fn main() { let args = CliArgs::parse(); env_logger::init(); - let stage_io = stage::StageIO::new(&args.stage_device, args.tty_speed).unwrap(); + let stage_io = StageIO::new(&args.stage_device, args.tty_speed).unwrap(); let mut s = stage::Stage::new(stage_io, 1.12).unwrap(); let origin = nalgebra::vector![3000.0, 0.0, -6000.0]; //println!("{}", s.version().unwrap()); diff --git a/hostcontrol/src/stage.rs b/hostcontrol/src/stage.rs index 8a4901b..1c4060a 100644 --- a/hostcontrol/src/stage.rs +++ b/hostcontrol/src/stage.rs @@ -1,7 +1,6 @@ //! Stage controller for openflexure-delta like stage controllers. -use log::debug; -use std::time::Duration; +use crate::stage_io::{StageIO, StageIOError}; use thiserror::Error; fn new_camera_rotation(theta: f64) -> nalgebra::Matrix3 { @@ -23,16 +22,6 @@ fn new_delta_into_cartesian(flex_h: f64, flex_a: f64, flex_b: f64) -> nalgebra:: ] } -#[derive(Error, Debug)] -pub enum StageIOError { - #[error("could not connect to stage controller")] - Open(#[from] serialport::Error), - #[error("error when sending data to the stage controller")] - Write(std::io::Error), - #[error("error when receiving data from the stage controller")] - Read(std::io::Error), -} - #[derive(Error, Debug)] pub enum StageError { #[error("Interface issue")] @@ -41,10 +30,6 @@ pub enum StageError { Mumble, } -pub struct StageIO { - serial: Box, -} - pub struct Stage { stage_io: StageIO, delta_pos: nalgebra::Vector3, @@ -52,43 +37,6 @@ pub struct Stage { delta_to_cartesian: nalgebra::Matrix3, } -pub type StageIOResult = std::result::Result; -impl StageIO { - pub fn new(port: &str, speed: u32) -> StageIOResult { - let serial = serialport::new(port, speed) - .timeout(Duration::from_secs(60)) - .open()?; - // TODO: read and discard initial characters; some devices like to be - // chatty on start-up. - Ok(Self { serial }) - } - - fn receive_until>(&mut self, needle: S) -> StageIOResult { - let mut res: Vec = vec![]; - loop { - let mut buf = [0u8; 1]; - self.serial - .read_exact(&mut buf) - .map_err(|e| StageIOError::Read(e))?; - res.push(buf[0]); - if res.ends_with(needle.as_ref().as_bytes()) { - return Ok(String::from_utf8_lossy(&res).to_string()); - } - } - } - - // Send request and wait for response deliminated with a newline - pub fn send_request>(&mut self, command: S) -> StageIOResult { - debug!("->: {:?}", command.as_ref()); - self.serial - .write_all(command.as_ref().as_bytes()) - .map_err(|e| StageIOError::Write(e))?; - let response = self.receive_until("\n")?; - debug!("<-: {:?}", response); - Ok(response.trim().to_string()) - } -} - pub type Result = std::result::Result; impl Stage { pub fn new(stage_io: StageIO, camera_rotation: f64) -> Result { diff --git a/hostcontrol/src/stage_io.rs b/hostcontrol/src/stage_io.rs new file mode 100644 index 0000000..d0cec47 --- /dev/null +++ b/hostcontrol/src/stage_io.rs @@ -0,0 +1,56 @@ +use log::debug; +use std::time::Duration; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum StageIOError { + #[error("could not connect to stage controller")] + Open(#[from] serialport::Error), + #[error("error when sending data to the stage controller")] + Write(std::io::Error), + #[error("error when receiving data from the stage controller")] + Read(std::io::Error), +} + +pub struct StageIO { + serial: Box, +} + +pub type StageIOResult = std::result::Result; +impl StageIO { + /// Create a new serial StageIO at given serial device and speed. + pub fn new(port: &str, speed: u32) -> StageIOResult { + let serial = serialport::new(port, speed) + .timeout(Duration::from_secs(60)) + .open()?; + // TODO: read and discard initial characters; some devices like to be + // chatty on start-up. + Ok(Self { serial }) + } + + /// Receive data until the given character string "needle" is seen. + fn receive_until>(&mut self, needle: S) -> StageIOResult { + let mut res: Vec = vec![]; + loop { + let mut buf = [0u8; 1]; + self.serial + .read_exact(&mut buf) + .map_err(|e| StageIOError::Read(e))?; + res.push(buf[0]); + if res.ends_with(needle.as_ref().as_bytes()) { + return Ok(String::from_utf8_lossy(&res).to_string()); + } + } + } + + /// Send request and wait for response deliminated with a newline + pub fn send_request>(&mut self, command: S) -> StageIOResult { + debug!("->: {:?}", command.as_ref()); + self.serial + .write_all(command.as_ref().as_bytes()) + .map_err(|e| StageIOError::Write(e))?; + let response = self.receive_until("\n")?; + debug!("<-: {:?}", response); + Ok(response.trim().to_string()) + } +}