auto conf sync to gui
This commit is contained in:
parent
27e69bf301
commit
ce223621d1
2 changed files with 57 additions and 13 deletions
|
@ -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!()}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue