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 common::{CamState, ControlPacket, SensorData, TelemetryPacket};
|
||||||
use anyhow::Result;
|
use anyhow::{Context, Ok, Result};
|
||||||
use tokio::sync::{broadcast, mpsc, watch};
|
use eframe::Storage;
|
||||||
|
use tokio::sync::{self, broadcast, mpsc, watch};
|
||||||
|
|
||||||
pub struct AutoConfig {
|
pub struct AutoConfig {
|
||||||
turn_gain: f32,
|
turn_gain: f32,
|
||||||
|
@ -10,14 +11,19 @@ pub struct AutoConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AutoInterface {
|
pub struct AutoInterface<'s> {
|
||||||
command_sender: Option<mpsc::Sender<ControlPacket>>,
|
command_sender: Option<mpsc::Sender<ControlPacket>>,
|
||||||
data_receiver: watch::Receiver<TelemetryPacket>,
|
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
|
/// 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 {
|
pub fn sensor_data(&mut self) -> SensorData {
|
||||||
self.data_receiver.borrow_and_update().sensors.clone()
|
self.data_receiver.borrow_and_update().sensors.clone()
|
||||||
}
|
}
|
||||||
|
@ -32,9 +38,16 @@ impl AutoInterface {
|
||||||
/// disable auto
|
/// disable auto
|
||||||
pub fn disable(&self) {unimplemented!()}
|
pub fn disable(&self) {unimplemented!()}
|
||||||
/// request auto enable, fails if the driver does not grant it
|
/// request auto enable, fails if the driver does not grant it
|
||||||
pub fn enable(&self) -> Result<()> {unimplemented!()}
|
pub fn enable(&mut self) -> Result<()> {
|
||||||
pub fn enabled(&self) -> bool {unimplemented!()}
|
self.enabled = self.command_sender.is_some();
|
||||||
pub fn conf(&self, key: &'static Configurable) -> f32 {unimplemented!()}
|
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!()}
|
fn send_message(&self, message: String) {unimplemented!()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
|
use std::{cell::OnceCell, collections::HashMap, path::PathBuf, sync::{atomic::Ordering, Arc}, time::Duration};
|
||||||
use std::{cell::OnceCell, path::PathBuf, sync::atomic::Ordering, time::Duration};
|
|
||||||
|
|
||||||
use common::{ControlPacket, TelemetryPacket};
|
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 image::ImageFormat;
|
||||||
use tokio::{runtime::Runtime, sync::{mpsc, watch::Receiver}};
|
use tokio::{runtime::Runtime, sync::{mpsc, watch::Receiver}};
|
||||||
use egui_toast::{Toast, Toasts};
|
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();
|
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 {
|
impl eframe::App for GUI {
|
||||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
let _ = GUI.set(ctx.clone());
|
let _ = GUI.set(ctx.clone());
|
||||||
|
@ -110,6 +121,10 @@ impl eframe::App for GUI {
|
||||||
storage.set_string("selected_auto", format!("{}",self.selected_auto));
|
storage.set_string("selected_auto", format!("{}",self.selected_auto));
|
||||||
|
|
||||||
POWER_THRESHOLD.store(self.volume_threshold, Ordering::Relaxed);
|
POWER_THRESHOLD.store(self.volume_threshold, Ordering::Relaxed);
|
||||||
|
|
||||||
|
for conf in CONFIGS {
|
||||||
|
configurator(ui, conf, storage);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
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