Implement simple GCode stage.
Easy experimenting with 3D printer or other CNC if open flexure is not available. Signed-off-by: Henner Zeller <h.zeller@acm.org>
This commit is contained in:
parent
4f620ad899
commit
ad9b1cb8c2
4 changed files with 72 additions and 9 deletions
45
hostcontrol/src/gcode_stage.rs
Normal file
45
hostcontrol/src/gcode_stage.rs
Normal file
|
|
@ -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<f64>,
|
||||
}
|
||||
|
||||
impl GCodeStage {
|
||||
pub fn new(stage_io: StageIO) -> Result<Self> {
|
||||
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<f64>) -> 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<f64> {
|
||||
self.max_range_μm
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for GCodeStage {
|
||||
fn drop(&mut self) {
|
||||
self.stage_io.send_request("M84\n").unwrap(); // switch off motors.
|
||||
}
|
||||
}
|
||||
|
|
@ -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<dyn XYStage> = 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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<f64> {
|
||||
nalgebra::matrix![
|
||||
|
|
@ -93,7 +93,7 @@ impl OpenFlexureStage {
|
|||
|
||||
impl XYStage for OpenFlexureStage {
|
||||
fn move_absolute_cartesian(&mut self, a: nalgebra::Vector3<f64>) -> 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<f64> {
|
||||
nalgebra::vector![10000.0, 10000.0, 5000.0]
|
||||
nalgebra::vector![10000.0, 10000.0, 5000.0]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
use crate::stage_io::StageIOError;
|
||||
use thiserror::Error;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue