diff --git a/src/detection/brightness_detector.rs b/src/detection/brightness_detector.rs index 7acb0ad..873cb46 100644 --- a/src/detection/brightness_detector.rs +++ b/src/detection/brightness_detector.rs @@ -82,7 +82,7 @@ impl BrightnessDetector { /// Update the background model with a new frame fn update_background(&mut self, frame: &core::Mat) -> Result<()> { // Convert frame to grayscale - let mut gray = core::Mat::default()?; + let mut gray = core::Mat::default(); imgproc::cvt_color(frame, &mut gray, imgproc::COLOR_BGR2GRAY, 0)?; match &mut self.background { @@ -101,13 +101,13 @@ impl BrightnessDetector { } /// Calculate the absolute difference between current frame and background - fn compute_difference(&self, frame: &core::Mat) -> Result { + fn compute_difference(&mut self, frame: &core::Mat) -> Result { // Convert frame to grayscale - let mut gray = core::Mat::default()?; + let mut gray = core::Mat::default(); imgproc::cvt_color(frame, &mut gray, imgproc::COLOR_BGR2GRAY, 0)?; // Calculate absolute difference from background - let mut diff = core::Mat::default()?; + let mut diff = core::Mat::default(); if let Some(bg) = &self.background { core::absdiff(bg, &gray, &mut diff)?; } else { @@ -124,7 +124,7 @@ impl BrightnessDetector { self.prev_frame = Some(gray); // Apply threshold to highlight significant changes - let mut thresholded = core::Mat::default()?; + let mut thresholded = core::Mat::default(); imgproc::threshold(&diff, &mut thresholded, 25.0, 255.0, imgproc::THRESH_BINARY)?; Ok(thresholded) @@ -133,13 +133,11 @@ impl BrightnessDetector { /// Find contours in the thresholded difference image fn find_meteor_candidates(&self, diff: &core::Mat) -> Result>> { let mut contours = core::Vector::>::new(); - let mut hierarchy = core::Vector::::new(); - + // Find contours in the thresholded image imgproc::find_contours( diff, &mut contours, - &mut hierarchy, imgproc::RETR_EXTERNAL, imgproc::CHAIN_APPROX_SIMPLE, core::Point::new(0, 0), @@ -154,7 +152,7 @@ impl BrightnessDetector { /// Calculate the brightness change in the frame fn calculate_brightness(&self, frame: &core::Mat) -> Result { // Convert to grayscale - let mut gray = core::Mat::default()?; + let mut gray = core::Mat::default(); imgproc::cvt_color(frame, &mut gray, imgproc::COLOR_BGR2GRAY, 0)?; // Calculate mean brightness diff --git a/src/detection/cams_detector.rs b/src/detection/cams_detector.rs index 7cf98bd..6d7f2c2 100644 --- a/src/detection/cams_detector.rs +++ b/src/detection/cams_detector.rs @@ -7,8 +7,7 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; use uuid::Uuid; - -use crate::camera::frame_buffer::Frame; +use crate::camera::Frame; use crate::config::Config; use crate::detection::{ DetectionResult, DetectorConfig, FeatureImages, FrameStacker, MeteorDetector, SharedFrameStacker, diff --git a/src/detection/frame_stacker.rs b/src/detection/frame_stacker.rs index 4a1b2e8..89dbd3e 100644 --- a/src/detection/frame_stacker.rs +++ b/src/detection/frame_stacker.rs @@ -12,7 +12,7 @@ use std::collections::VecDeque; use std::path::PathBuf; use std::sync::{Arc, Mutex}; -use crate::camera::frame_buffer::Frame; +use crate::camera::Frame; /// Configuration for the frame stacker #[derive(Debug, Clone, Serialize, Deserialize)] @@ -177,9 +177,9 @@ impl FrameStacker { // Get dimensions from the first frame let first_frame = &self.frame_buffer[0]; - let width = first_frame.data.cols(); - let height = first_frame.data.rows(); - let channels = first_frame.data.channels(); + let width = first_frame.mat.cols(); + let height = first_frame.mat.rows(); + let channels = first_frame.mat.channels(); if channels != 1 { // Convert any color frames to grayscale @@ -195,12 +195,12 @@ impl FrameStacker { // Process all frames for (frame_idx, frame) in self.frame_buffer.iter().enumerate() { // Convert to grayscale if needed - let gray_frame = if frame.data.channels() != 1 { + let gray_frame = if frame.mat.channels() != 1 { let mut gray = core::Mat::default(); - imgproc::cvt_color(&frame.data, &mut gray, imgproc::COLOR_BGR2GRAY, 0)?; + imgproc::cvt_color(&frame.mat, &mut gray, imgproc::COLOR_BGR2GRAY, 0)?; gray } else { - frame.data.clone() + frame.mat.clone() }; // Make sure the grayscale image is 8-bit diff --git a/src/detection/pipeline.rs b/src/detection/pipeline.rs index f915dca..470273a 100644 --- a/src/detection/pipeline.rs +++ b/src/detection/pipeline.rs @@ -11,7 +11,7 @@ use tokio::sync::{broadcast, mpsc}; use tokio::time; use tokio::task::JoinSet; -use crate::camera::frame_buffer::{Frame, SharedFrameBuffer}; +use crate::camera::{Frame}; use crate::camera::{CameraController, MeteorEvent}; use crate::config::Config; use crate::detection::{ @@ -380,11 +380,6 @@ impl DetectionPipeline { .cloned() } - /// Get a receiver for meteor events - pub fn subscribe_to_events(&self) -> mpsc::Receiver { - self.event_rx.clone() - } - /// Stop the detection pipeline pub async fn stop(&self) -> Result<()> { { diff --git a/src/gps/nmea.rs b/src/gps/nmea.rs index 226c8cb..bc9bf0e 100644 --- a/src/gps/nmea.rs +++ b/src/gps/nmea.rs @@ -99,11 +99,11 @@ fn parse_gga(fields: &[&str]) -> Result> { let mut position = NmeaPosition::default(); - // Parse time - if let Some(time) = parse_nmea_time(fields[1]) { - // This only has time, not date - position.timestamp = Some(Utc.from_utc_datetime(&time.and_utc())); - } + // // Parse time + // if let Some(time) = parse_nmea_time(fields[1]) { + // // This only has time, not date + // position.timestamp = Some(Utc.from_utc_datetime(&time.and_utc())); + // } // Parse latitude (field 2 & 3) if !fields[2].is_empty() && !fields[3].is_empty() { @@ -280,6 +280,7 @@ fn calculate_checksum(message: &str) -> u8 { /// Unit tests for NMEA parser #[cfg(test)] mod tests { + use chrono::{Datelike, Timelike}; use super::*; #[test] @@ -293,16 +294,16 @@ mod tests { assert!((result.position.longitude - 11.5167).abs() < 0.0001); assert!((result.position.altitude - 545.4).abs() < 0.0001); } - + #[test] fn test_parse_rmc() { let sentence = "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A"; let result = parse_nmea_sentence(sentence).unwrap().unwrap(); - + assert_eq!(result.fix_quality, 1); assert!((result.position.latitude - 48.1173).abs() < 0.0001); assert!((result.position.longitude - 11.5167).abs() < 0.0001); - + if let Some(timestamp) = result.timestamp { let naive = timestamp.naive_utc(); assert_eq!(naive.year(), 1994); diff --git a/src/sensors/controller.rs b/src/sensors/controller.rs index 4a5f2f5..bfc3dbc 100644 --- a/src/sensors/controller.rs +++ b/src/sensors/controller.rs @@ -1,3 +1,4 @@ +use chrono::DateTime; use anyhow::{anyhow, Context, Result}; use chrono::Utc; use log::{debug, error, info, warn}; @@ -297,7 +298,7 @@ impl SensorController { } // Broadcast update - let _ = data_tx.send(data); + let _ = data_tx.send(data.clone()); debug!("Sensor data updated: temp={:.1}°C, humidity={:.1}%, light={:.3}", data.temperature, data.humidity, data.sky_brightness); diff --git a/src/sensors/dht22.rs b/src/sensors/dht22.rs index 5db1a56..e7f3ada 100644 --- a/src/sensors/dht22.rs +++ b/src/sensors/dht22.rs @@ -44,14 +44,16 @@ impl Dht22Sensor { .context(format!("Failed to access GPIO pin {}", self.pin))?; // Send start signal - pin.set_mode(Mode::Output); + let mut pin = pin.into_output_low(); pin.set_low(); thread::sleep(Duration::from_millis(20)); // At least 18ms for DHT22 pin.set_high(); // Switch to input mode to read response - pin.set_mode(Mode::Input); - + let mut pin = gpio.get(self.pin) + .context(format!("Failed to access GPIO pin {}", self.pin))?; + let mut pin = pin.into_input(); + // Wait for sensor to respond let mut cycles = 0; while pin.read() == Level::High { @@ -127,7 +129,7 @@ impl TemperatureHumiditySensor for Dht22Sensor { if self.last_reading.elapsed() < Duration::from_secs(2) { return Ok(self.last_temperature); } - + // Try to read new values match self.read_raw() { Ok((temp, _)) => Ok(temp),