fix: compile error
This commit is contained in:
parent
92eee703a1
commit
cc7c5c92b0
@ -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<Self> {
|
||||
// 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<Utc> {
|
||||
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<GeoPosition> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user