microscope-control/hostcontrol/src/main.rs

101 lines
2.6 KiB
Rust

use clap::{Parser, ValueEnum};
use image::RgbImage;
use std::path::PathBuf;
mod camera;
mod gcode_stage;
mod openflexure_stage;
mod stage_io;
use crate::camera::Camera;
use crate::stage_io::StageIO;
use crate::xy_stage::XYStage;
mod xy_stage;
#[derive(clap::Parser, Debug)]
#[command(version, about, long_about = None)]
struct CliArgs {
/// Interface to talk to movement stage
#[arg(long, default_value = "/dev/ttyACM0")]
stage_device: String,
/// Speed of the stage device (bps)
#[arg(long, default_value = "115200")]
tty_speed: u32,
/// Stage movement backend
#[arg(long, value_enum)]
backend: Backend,
/// Id of camera to fetch images from.
#[arg(long, default_value = "0")]
camera_index: u32,
/// Directory all captured images are stored.
#[arg(long, value_name = "out-dir")]
output_directory: PathBuf,
}
// [derive(DebugCopy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
#[derive(Debug, Clone, ValueEnum)]
enum Backend {
/// OpenFlexure stage
OpenFlexure,
/// GCode stage
GCode,
}
fn store_image(number: u32, pos: nalgebra::Vector3<f64>, dir: &PathBuf, img: &RgbImage) {
let img_file = &dir.join(format!("img-{:05}-{:0},{:0}.png", number, pos[0], pos[1]));
img.save(img_file).unwrap();
}
fn main() {
env_logger::init();
let args = CliArgs::parse();
if !args.output_directory.is_dir() {
panic!("--out-dir needs to be an existing directory");
}
let origin = nalgebra::vector![0.0, 0.0, 0.0];
// Picture source
let mut cam = Camera::new(args.camera_index).unwrap();
cam.capture().unwrap(); // Warm up camera.
// Movement
let stage_io = StageIO::new(&args.stage_device, args.tty_speed).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())
}
};
// Local testing. Just take a line of pictures.
let mut max_xy = stage.get_range();
// Only interested in lerp-ing X for now.
max_xy[1] = 0.0;
max_xy[2] = 0.0;
for n in 0..10 {
let pos = max_xy * n as f64 / 10.0;
stage.move_absolute_cartesian(pos).unwrap();
store_image(n, pos, &args.output_directory, &cam.capture().unwrap());
}
}
#[derive(Default)]
struct App {}
impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("My egui Application");
});
}
}