1
Fork 0

auto conf sync to gui

This commit is contained in:
Andy Killorin 2025-03-08 20:47:52 -05:00
parent 27e69bf301
commit ce223621d1
Signed by: ank
GPG key ID: 23F9463ECB67FE8C
2 changed files with 57 additions and 13 deletions

View file

@ -1,8 +1,9 @@
use std::{collections::VecDeque, ops::{Deref, Div, Index, Range, Sub}};
use std::{collections::VecDeque, ops::{Deref, Div, Index, Range, Sub}, sync::Arc};
use common::{CamState, ControlPacket, SensorData, TelemetryPacket};
use anyhow::Result;
use tokio::sync::{broadcast, mpsc, watch};
use anyhow::{Context, Ok, Result};
use eframe::Storage;
use tokio::sync::{self, broadcast, mpsc, watch};
pub struct AutoConfig {
turn_gain: f32,
@ -10,14 +11,19 @@ pub struct AutoConfig {
}
#[derive(Clone)]
pub struct AutoInterface {
pub struct AutoInterface<'s> {
command_sender: Option<mpsc::Sender<ControlPacket>>,
data_receiver: watch::Receiver<TelemetryPacket>,
config: &'s dyn Storage,
enabled: bool,
}
impl AutoInterface {
impl<'s> AutoInterface<'s> {
/// change active command, fails if not in control
pub fn run_command(&self, command: ControlPacket) -> Result<()> {unimplemented!()}
pub async fn run_command(&self, command: ControlPacket) -> Result<()> {
self.command_sender.as_ref().context("no sender")?.send(command).await?;
Ok(())
}
pub fn sensor_data(&mut self) -> SensorData {
self.data_receiver.borrow_and_update().sensors.clone()
}
@ -32,9 +38,16 @@ impl AutoInterface {
/// disable auto
pub fn disable(&self) {unimplemented!()}
/// request auto enable, fails if the driver does not grant it
pub fn enable(&self) -> Result<()> {unimplemented!()}
pub fn enabled(&self) -> bool {unimplemented!()}
pub fn conf(&self, key: &'static Configurable) -> f32 {unimplemented!()}
pub fn enable(&mut self) -> Result<()> {
self.enabled = self.command_sender.is_some();
Ok(())
}
pub fn enabled(&self) -> bool { self.enabled}
pub fn conf(&self, key: &'static Configurable) -> f32 {
self.config.get_string(&key.name)
.map(|s| s.parse().ok())
.flatten().unwrap_or(key.default)
}
fn send_message(&self, message: String) {unimplemented!()}
}

View file

@ -1,13 +1,12 @@
use std::{cell::OnceCell, path::PathBuf, sync::atomic::Ordering, time::Duration};
use std::{cell::OnceCell, collections::HashMap, path::PathBuf, sync::{atomic::Ordering, Arc}, time::Duration};
use common::{ControlPacket, TelemetryPacket};
use eframe::{egui::{self, containers, Align2, Checkbox, Context, IconData, Id, ImageSource, Label}, Storage};
use eframe::{egui::{self, containers, Align2, Checkbox, Context, IconData, Id, ImageSource, Label, Ui}, Storage};
use image::ImageFormat;
use tokio::{runtime::Runtime, sync::{mpsc, watch::Receiver}};
use egui_toast::{Toast, Toasts};
use crate::{storage_dir::storage_dir, POWER_THRESHOLD};
use crate::{auto::Configurable, storage_dir::storage_dir, POWER_THRESHOLD};
pub const GUI: OnceCell<Context> = OnceCell::new();
@ -88,6 +87,18 @@ impl GUI {
}
}
// dupe from auto crate for testing
const AUTO_GAP: Configurable = Configurable::new("auto minimum gap").range(0. .. 300.).default(140.)
.description("distance (mm) distance measurements must instantaneously drop to indicate a detection. This should line up with the size of the smallest robot you compete against");
const AUTO_SELF_OCCLUSION: Configurable = Configurable::new("auto self occlusion").range(0. .. 200.).default(143.)
.description("distance (mm) below which measurements are considered noise in the scan phase");
#[unsafe(no_mangle)]
pub static CONFIGS: &[Configurable] = &[
AUTO_GAP,
AUTO_SELF_OCCLUSION,
];
impl eframe::App for GUI {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
let _ = GUI.set(ctx.clone());
@ -110,6 +121,10 @@ impl eframe::App for GUI {
storage.set_string("selected_auto", format!("{}",self.selected_auto));
POWER_THRESHOLD.store(self.volume_threshold, Ordering::Relaxed);
for conf in CONFIGS {
configurator(ui, conf, storage);
}
});
egui::CentralPanel::default().show(ctx, |ui| {
@ -144,3 +159,19 @@ impl eframe::App for GUI {
}
}
}
fn configurator(ui: &mut Ui, config: &Configurable, map: &mut dyn Storage) {
ui.add(egui::Slider::from_get_set(config.min as f64 ..= config.max as f64, |value| {
match value {
Some(value) => {
map.set_string(&config.name,format!("{value}"));
value
},
None => map.get_string(&config.name).map(|s| s.parse().ok()).flatten().unwrap_or(config.default as f64),
}
}).text(config.name));
if let Some(description) = config.description {
ui.label(description);
}
}