From cc7c5c92b0abfac61a9ecbb1a4ce5052a5ef3cd4 Mon Sep 17 00:00:00 2001 From: grabbit Date: Fri, 21 Mar 2025 01:53:20 +0800 Subject: [PATCH] fix: compile error --- src/gps/controller.rs | 139 +++++++++++++++++++++--------------------- 1 file changed, 69 insertions(+), 70 deletions(-) diff --git a/src/gps/controller.rs b/src/gps/controller.rs index 738cf33..f93cdc9 100644 --- a/src/gps/controller.rs +++ b/src/gps/controller.rs @@ -2,12 +2,13 @@ use anyhow::{anyhow, Context, Result}; use chrono::{DateTime, Duration, Utc}; use log::{debug, error, info, warn}; use rppal::gpio::{Gpio, InputPin, Trigger}; -use serialport::{SerialPort, SerialPortSettings}; +use serialport::{SerialPort}; use std::io::{BufRead, BufReader}; use std::path::Path; use std::sync::{Arc, Mutex}; use std::thread; use std::time; +use serialport::DataBits::Eight; use tokio::sync::broadcast; use crate::gps::nmea::{parse_nmea_sentence, NmeaPosition}; @@ -68,17 +69,17 @@ impl GpsController { pub async fn new(config: &crate::Config) -> Result { // Extract GPS settings from config let gps_config = config.gps.clone(); - + // Create broadcast channel for position updates let (position_tx, _) = broadcast::channel(10); - + // Use fallback position as initial position if GPS is not enabled let initial_position = if gps_config.enable_gps { GeoPosition::default() } else { gps_config.fallback_position }; - + Ok(Self { config: gps_config, port: None, @@ -93,47 +94,45 @@ impl GpsController { gps_state: GpsState::default(), }) } - + /// Initialize the GPS module pub async fn initialize(&mut self) -> Result<()> { // Check if GPS is enabled in config if !self.config.enable_gps { info!("GPS module disabled in configuration. Using fallback position."); self.gps_state.degraded = true; - + // Set fallback position let mut pos = self.position.lock().unwrap(); *pos = self.config.fallback_position; - + return Ok(()); } - + let mut init_failed = false; - + // Open the serial port - let settings = SerialPortSettings { - baud_rate: self.config.baud_rate, - data_bits: serialport::DataBits::Eight, - flow_control: serialport::FlowControl::None, - parity: serialport::Parity::None, - stop_bits: serialport::StopBits::One, - timeout: time::Duration::from_millis(1000), - }; - - match serialport::open_with_settings(&self.config.port, &settings) { + + let port = serialport::new(&self.config.port, self.config.baud_rate) + .data_bits(Eight) + .flow_control(serialport::FlowControl::None) + .parity(serialport::Parity::None) + .stop_bits(serialport::StopBits::One) + .timeout(time::Duration::from_millis(1000)); + match port.open() { Ok(port) => { self.port = Some(port); self.gps_state.initialized = true; }, Err(e) => { self.gps_state.init_failures += 1; - + if self.config.allow_degraded_mode { - warn!("Failed to open GPS port {}: {}. Using fallback position.", + warn!("Failed to open GPS port {}: {}. Using fallback position.", self.config.port, e); self.gps_state.degraded = true; init_failed = true; - + // Set fallback position let mut pos = self.position.lock().unwrap(); *pos = self.config.fallback_position; @@ -142,7 +141,7 @@ impl GpsController { } } } - + // Initialize PPS pin if enabled and GPS initialized successfully if self.config.use_pps && !self.gps_state.degraded { match Gpio::new() { @@ -150,7 +149,7 @@ impl GpsController { match gpio.get(self.config.pps_pin) { Ok(pin) => { let mut input_pin = pin.into_input(); - + // Set up PPS edge detection (rising edge) let last_pps = self.last_pps.clone(); match input_pin.set_async_interrupt(Trigger::RisingEdge, move |_| { @@ -168,7 +167,7 @@ impl GpsController { } }, Err(e) => { - warn!("Failed to access GPIO pin {}: {}. PPS sync disabled.", + warn!("Failed to access GPIO pin {}: {}. PPS sync disabled.", self.config.pps_pin, e); } } @@ -180,7 +179,7 @@ impl GpsController { } else if !self.config.use_pps { info!("PPS signal detection disabled in configuration"); } - + if self.gps_state.degraded { if self.config.allow_degraded_mode { info!("GPS module initialized in degraded mode (using fallback position)"); @@ -193,38 +192,38 @@ impl GpsController { Ok(()) } } - + /// Start GPS processing pub async fn start(&self) -> Result<()> { // Handle degraded mode if self.gps_state.degraded { info!("Starting GPS in degraded mode (using fallback position)"); - + // Set fallback position and status { let mut pos = self.position.lock().unwrap(); *pos = self.config.fallback_position; - + let mut status = self.sync_status.lock().unwrap(); *status = SyncStatus::NoSync; - + // Send an initial position update with fallback let _ = self.position_tx.send(self.config.fallback_position); } - + { let mut is_running = self.is_running.lock().unwrap(); *is_running = true; } - + return Ok(()); } - + // Normal mode - require initialized GPS if self.port.is_none() { return Err(anyhow!("GPS not initialized")); } - + { let mut is_running = self.is_running.lock().unwrap(); if *is_running { @@ -233,7 +232,7 @@ impl GpsController { } *is_running = true; } - + // Clone Arc references for the background task let port_name = self.config.port.clone(); let position = self.position.clone(); @@ -242,30 +241,30 @@ impl GpsController { let last_update = self.last_update.clone(); let position_tx = self.position_tx.clone(); let is_running = self.is_running.clone(); - + // Clone fallback position in case we need it later let fallback_position = self.config.fallback_position; let allow_degraded = self.config.allow_degraded_mode; - + // Create a separate thread for GPS processing (blocking I/O) thread::spawn(move || { info!("Starting GPS processing on port {}", port_name); - + // Get the port let port = match serialport::open(&port_name) { Ok(port) => port, Err(e) => { error!("Failed to open GPS port: {}", e); - + // Use fallback position if degraded mode allowed if allow_degraded { warn!("Using fallback position due to GPS port error"); let mut pos = position.lock().unwrap(); *pos = fallback_position; - + let _ = position_tx.send(fallback_position); } - + { let mut is_running = is_running.lock().unwrap(); *is_running = false; @@ -273,13 +272,13 @@ impl GpsController { return; } }; - + let reader = BufReader::new(port); - + // Set a timeout for acquiring fix let start_time = Utc::now(); let mut fix_acquired = false; - + for line in reader.lines() { // Check if we should exit { @@ -288,24 +287,24 @@ impl GpsController { break; } } - + // Check if we've been waiting too long for a fix if !fix_acquired && allow_degraded { let elapsed = Utc::now() - start_time; if elapsed > Duration::seconds(30) { // 30 second timeout for initial fix warn!("Timeout waiting for GPS fix, using fallback position"); - + // Set fallback position { let mut pos = position.lock().unwrap(); *pos = fallback_position; let _ = position_tx.send(fallback_position); } - + // Continue trying, but we at least have a fallback now } } - + match line { Ok(sentence) => { if let Ok(Some(nmea_pos)) = parse_nmea_sentence(&sentence) { @@ -313,17 +312,17 @@ impl GpsController { { let mut pos = position.lock().unwrap(); *pos = nmea_pos.position; - + // Send position update let _ = position_tx.send(nmea_pos.position); } - + // Update satellites { let mut sats = satellites.lock().unwrap(); *sats = nmea_pos.satellites; } - + // Update sync status { let mut status = sync_status.lock().unwrap(); @@ -332,13 +331,13 @@ impl GpsController { fix_acquired = true; } } - + // Update last update time { let mut update = last_update.lock().unwrap(); *update = Some(Utc::now()); } - + debug!("GPS update: lat={:.6}, lon={:.6}, alt={:.1}, satellites={}", nmea_pos.position.latitude, nmea_pos.position.longitude, @@ -351,18 +350,18 @@ impl GpsController { } } } - + info!("GPS processing stopped"); { let mut is_running = is_running.lock().unwrap(); *is_running = false; } }); - + info!("GPS processing started"); Ok(()) } - + /// Stop GPS processing pub async fn stop(&self) -> Result<()> { { @@ -373,12 +372,12 @@ impl GpsController { } *is_running = false; } - + // The background thread will notice the is_running flag and exit info!("GPS processing stopping (may take a moment to complete)"); Ok(()) } - + /// Get the current GPS status pub fn get_status(&self) -> GpsStatus { let position = self.position.lock().unwrap().clone(); @@ -388,14 +387,14 @@ impl GpsController { SyncStatus::GpsOnly => "gps_only", SyncStatus::FullSync => "full_sync", }.to_string(); - + // Calculate time accuracy estimate let time_accuracy_ms = match *self.sync_status.lock().unwrap() { SyncStatus::NoSync => 1000.0, // 1 second SyncStatus::GpsOnly => 100.0, // 100 ms SyncStatus::FullSync => 1.0, // 1 ms }; - + GpsStatus { position, satellites, @@ -405,11 +404,11 @@ impl GpsController { camera_orientation: self.config.camera_orientation, } } - + /// Get a precise UTC timestamp using PPS if available pub fn get_precise_time(&self) -> DateTime { let now = Utc::now(); - + // If we have PPS sync, adjust to the last PPS pulse if let SyncStatus::FullSync = *self.sync_status.lock().unwrap() { if let Some(last_pps) = *self.last_pps.lock().unwrap() { @@ -420,40 +419,40 @@ impl GpsController { } } } - + // Fall back to system time now } - + /// Get current position pub fn get_position(&self) -> GeoPosition { self.position.lock().unwrap().clone() } - + /// Subscribe to position updates pub fn subscribe(&self) -> broadcast::Receiver { self.position_tx.subscribe() } - + /// Check if the GPS has a valid fix pub fn has_fix(&self) -> bool { // In degraded mode with fallback, pretend we have a fix if self.gps_state.degraded && self.config.allow_degraded_mode { return true; } - + // Otherwise check actual sync status match *self.sync_status.lock().unwrap() { SyncStatus::NoSync => false, _ => true, } } - + /// Update the camera orientation pub fn set_camera_orientation(&mut self, orientation: CameraOrientation) { self.config.camera_orientation = orientation; } - + /// Get the camera orientation pub fn get_camera_orientation(&self) -> CameraOrientation { self.config.camera_orientation @@ -465,7 +464,7 @@ impl Drop for GpsController { // Ensure the GPS processing is stopped let mut is_running = self.is_running.lock().unwrap(); *is_running = false; - + // PPS pin will be dropped automatically, removing the interrupt } }