forked from fafo/microscope-control
Break out stage IO into separate file.
Signed-off-by: Henner Zeller <h.zeller@acm.org>
This commit is contained in:
parent
4e946eef77
commit
cc8152a75d
3 changed files with 61 additions and 54 deletions
|
|
@ -3,6 +3,9 @@ use std::{thread::sleep, time::Duration};
|
||||||
|
|
||||||
mod stage;
|
mod stage;
|
||||||
|
|
||||||
|
mod stage_io;
|
||||||
|
use crate::stage_io::StageIO;
|
||||||
|
|
||||||
#[derive(clap::Parser, Debug)]
|
#[derive(clap::Parser, Debug)]
|
||||||
#[command(version, about, long_about = None)]
|
#[command(version, about, long_about = None)]
|
||||||
struct CliArgs {
|
struct CliArgs {
|
||||||
|
|
@ -18,7 +21,7 @@ struct CliArgs {
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = CliArgs::parse();
|
let args = CliArgs::parse();
|
||||||
env_logger::init();
|
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 mut s = stage::Stage::new(stage_io, 1.12).unwrap();
|
||||||
let origin = nalgebra::vector![3000.0, 0.0, -6000.0];
|
let origin = nalgebra::vector![3000.0, 0.0, -6000.0];
|
||||||
//println!("{}", s.version().unwrap());
|
//println!("{}", s.version().unwrap());
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
//! Stage controller for openflexure-delta like stage controllers.
|
//! Stage controller for openflexure-delta like stage controllers.
|
||||||
|
|
||||||
use log::debug;
|
use crate::stage_io::{StageIO, StageIOError};
|
||||||
use std::time::Duration;
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
fn new_camera_rotation(theta: f64) -> nalgebra::Matrix3<f64> {
|
fn new_camera_rotation(theta: f64) -> nalgebra::Matrix3<f64> {
|
||||||
|
|
@ -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)]
|
#[derive(Error, Debug)]
|
||||||
pub enum StageError {
|
pub enum StageError {
|
||||||
#[error("Interface issue")]
|
#[error("Interface issue")]
|
||||||
|
|
@ -41,10 +30,6 @@ pub enum StageError {
|
||||||
Mumble,
|
Mumble,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StageIO {
|
|
||||||
serial: Box<dyn serialport::SerialPort>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Stage {
|
pub struct Stage {
|
||||||
stage_io: StageIO,
|
stage_io: StageIO,
|
||||||
delta_pos: nalgebra::Vector3<i32>,
|
delta_pos: nalgebra::Vector3<i32>,
|
||||||
|
|
@ -52,43 +37,6 @@ pub struct Stage {
|
||||||
delta_to_cartesian: nalgebra::Matrix3<f64>,
|
delta_to_cartesian: nalgebra::Matrix3<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type StageIOResult<T> = std::result::Result<T, StageIOError>;
|
|
||||||
impl StageIO {
|
|
||||||
pub fn new(port: &str, speed: u32) -> StageIOResult<Self> {
|
|
||||||
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<S: AsRef<str>>(&mut self, needle: S) -> StageIOResult<String> {
|
|
||||||
let mut res: Vec<u8> = 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<S: AsRef<str>>(&mut self, command: S) -> StageIOResult<String> {
|
|
||||||
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<T> = std::result::Result<T, StageError>;
|
pub type Result<T> = std::result::Result<T, StageError>;
|
||||||
impl Stage {
|
impl Stage {
|
||||||
pub fn new(stage_io: StageIO, camera_rotation: f64) -> Result<Self> {
|
pub fn new(stage_io: StageIO, camera_rotation: f64) -> Result<Self> {
|
||||||
|
|
|
||||||
56
hostcontrol/src/stage_io.rs
Normal file
56
hostcontrol/src/stage_io.rs
Normal file
|
|
@ -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<dyn serialport::SerialPort>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type StageIOResult<T> = std::result::Result<T, StageIOError>;
|
||||||
|
impl StageIO {
|
||||||
|
/// Create a new serial StageIO at given serial device and speed.
|
||||||
|
pub fn new(port: &str, speed: u32) -> StageIOResult<Self> {
|
||||||
|
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<S: AsRef<str>>(&mut self, needle: S) -> StageIOResult<String> {
|
||||||
|
let mut res: Vec<u8> = 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<S: AsRef<str>>(&mut self, command: S) -> StageIOResult<String> {
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue