summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorAndy Wortman <ixineeringeverywhere@gmail.com>2019-07-27 20:07:05 -0700
committerAndy Wortman <ixineeringeverywhere@gmail.com>2019-07-27 20:07:05 -0700
commit144854e4b1a7ac38c5ddd2b0d45c495f491aa5dc (patch)
tree55306a36cfe8fef91a38496510acf34a771e582e /src/main.rs
parent0d887779b8dee042999d04a29d4a095a3df93a6c (diff)
significant rewrite for threaded qhy operation
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs172
1 files changed, 167 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs
index 7275c96..dc70da6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,20 +7,181 @@
mod asicam;
mod qhyccd;
+#[macro_use]
+extern crate crossbeam_channel;
+
+use crossbeam_channel::{Sender, Receiver};
+use crossbeam_channel::unbounded;
+
+use std::time::Duration;
+
use crate::asicam::ASICamera2::{ControlType, ImageType};
use crate::asicam::Camera;
+use crate::qhyccd::QHYResponse;
+use crate::qhyccd::QHYMessage;
+
+use std::path::Path;
+use std::fs::File;
+use std::io::BufWriter;
+
+use png::HasParameters;
+
+fn record_image(data: &[u8], dimensions: Dimensions, target: &'static str, image_id: u32) {
+ let path_string = format!("{}_{}.png", target, image_id);
+ println!("writing {}..", path_string);
+ let dest = Path::new(&path_string);
+ let file = File::create(dest).unwrap();
+ let ref mut w = BufWriter::new(file);
+ let mut encoder = png::Encoder::new(w, dimensions.width, dimensions.height);
+ let color_type = if dimensions.channels == 3 {
+ png::ColorType::RGB
+ } else if dimensions.channels == 1 {
+ png::ColorType::Grayscale
+ } else { panic!("Unsupported channel count: {}", dimensions.channels); };
+
+ let bitness = if dimensions.bpp == 8 {
+ png::BitDepth::Eight
+ } else if dimensions.bpp == 16 {
+ png::BitDepth::Sixteen
+ } else {
+ panic!("Unknwon bitness: {}", dimensions.bpp);
+ };
+ encoder.set(color_type).set(bitness);
+ let mut writer = encoder.write_header().unwrap();
+ writer.write_image_data(data).unwrap();
+ println!("image written!");
+}
+
fn main() {
let test = true;
-// println!("Doing qhy...");
-// operate_qhy(test);
- println!("Doing asi...");
- operate_asi(test);
+ println!("Doing qhy...");
+ let (image_writer, image_reader) = unbounded();
+ let (frame_sender, free_frames) = unbounded();
+
+ std::thread::spawn(move || {
+ loop {
+ select! {
+ recv(image_reader) -> msg => {
+ match msg {
+ Ok(ImageInfo { mut data, dimensions, target, image_id }) => {
+ qhyccd::fix_channels_and_endianness(data.as_mut_slice());
+ record_image(data.as_slice(), dimensions, target, image_id);
+ println!("pretend i wrote image {}_{}", target, image_id);
+ frame_sender.send(data).unwrap();
+ }
+ Err(RecvError) => {
+ // something in the application has crashed. time 2 die
+ return;
+ }
+ }
+ }
+ }
+ }
+ });
+
+ operate_qhy("dark_gain_4000", None, free_frames, image_writer);
+// println!("Doing asi...");
+// operate_asi(test);
+}
+
+#[derive(Debug, Copy, Clone)]
+struct Dimensions {
+ width: u32,
+ height: u32,
+ bpp: u8,
+ channels: u8,
}
-fn operate_qhy(test: bool) {
+impl Dimensions {
+ pub fn new(width: u32, height: u32, bpp: u8, channels: u8) -> Self {
+ Dimensions { width, height, bpp, channels }
+ }
+}
+
+struct ImageInfo {
+ data: Vec<u8>,
+ dimensions: Dimensions,
+ target: &'static str,
+ image_id: u32
+}
+
+enum ImageWriter {
+ FrameReady(Vec<u8>, Dimensions, &'static str, u32)
+}
+
+fn operate_qhy(target: &'static str, count: Option<u32>, mut free_frames: Receiver<Vec<u8>>, mut image_writer: Sender<ImageInfo>) {
use crate::qhyccd::Control;
println!("Operating on qhy camera ... or i'll die trying");
+ let (mut camera_rx, mut camera_tx) = qhyccd::connect(0).unwrap();
+
+ let mut image_id = 0u32;
+ let mut settings_copy = qhyccd::Settings::default();
+
+ camera_tx.send(QHYMessage::SetControl(Control::Exposure, 20000000.0)).unwrap();
+ camera_tx.send(QHYMessage::SetControl(Control::Gain, 4000.0)).unwrap();
+ camera_tx.send(QHYMessage::SetControl(Control::Offset, 00.0)).unwrap();
+ camera_tx.send(QHYMessage::SetControl(Control::Cooler, 27.0)).unwrap();
+ camera_tx.send(QHYMessage::SetControl(Control::USBTraffic, 60.0)).unwrap();
+ camera_tx.send(QHYMessage::SetControl(Control::Color, 0.0)).unwrap(); // disable color
+// camera.set_roi(0, 0, 1920 * 2, 1080 * 2).unwrap();
+// println!("Gain: {:?}", camera.get_param_limits(Control::ManulPwm));
+// println!("cur pwm ???: {}", camera.get_param(Control::CurPWM));
+ camera_tx.send(QHYMessage::BeginCapture).unwrap();
+
+ loop {
+ select! {
+ recv(free_frames) -> msg => {
+ match msg {
+ Ok(buffer) => {
+ camera_tx.send(QHYMessage::FrameAvailable(buffer)).unwrap();
+ },
+ Err(RecvError) => {
+ // disconnected. nothing we can do but to..
+ return;
+ }
+ }
+ },
+ recv(camera_rx) -> msg => {
+ match msg {
+ Ok(QHYResponse::CurrentControlValue(control, value)) => {
+ println!("Control {:?} value: {}", control, value);
+ }
+ Ok(QHYResponse::InitializationError) => {
+ println!("Failed to initialize camera, exiting...");
+ return;
+ }
+ Ok(QHYResponse::Shutdown) => {
+ return;
+ }
+ Ok(QHYResponse::UpdatedSettings(settings)) => {
+ settings_copy = settings;
+ }
+ Ok(QHYResponse::Data(data, dimensions)) => {
+ image_writer.send(ImageInfo { data, dimensions, target, image_id: image_id }).unwrap();
+ // images.log(target, image_id, settings_copy);
+ image_id += 1;
+ if Some(image_id) == count {
+ camera_tx.send(QHYMessage::Shutdown);
+ }
+ }
+ Ok(QHYResponse::DroppedFrame) => {
+ println!("Dropped frame...");
+ }
+ Err(RecvError) => {
+ // camera is closed. hopefully it just shut down? but maybe crashed!!
+ return;
+ }
+ }
+ }
+ default(Duration::from_millis(2000)) => {
+ camera_tx.send(
+ QHYMessage::QueryControl(Control::CurTemp)
+ );
+ }
+ }
+ }
+ /*
let t = std::thread::spawn(move || {
let mut camera = qhyccd::acquire(0).unwrap();
camera.set_defaults().unwrap();
@@ -52,6 +213,7 @@ fn operate_qhy(test: bool) {
camera.release().unwrap();
});
t.join();
+ */
}
fn operate_asi(test: bool) {