mirror of
https://github.com/hubaldv/bioz-host-rs.git
synced 2025-12-06 05:11:17 +00:00
Added in seperate plots.
This commit is contained in:
61
src/app.rs
61
src/app.rs
@@ -1,8 +1,7 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use atomic_float::AtomicF32;
|
||||
use tokio::{sync::mpsc::{Sender}};
|
||||
|
||||
use eframe::egui::{self, Color32, DragValue, Key, Layout, Modifiers, };
|
||||
@@ -13,7 +12,6 @@ use crate::plot::TimeSeriesPlot;
|
||||
use crate::signals::FrequencySignal;
|
||||
|
||||
pub struct App {
|
||||
frequency: f32,
|
||||
run_impedancemeter_tx: Sender<FrequencySignal>,
|
||||
pub magnitude: Arc<Mutex<f32>>,
|
||||
pub phase: Arc<Mutex<f32>>,
|
||||
@@ -21,12 +19,12 @@ pub struct App {
|
||||
pub phase_series: Arc<Mutex<TimeSeriesPlot>>,
|
||||
pub connected: Arc<AtomicBool>,
|
||||
pub on: bool,
|
||||
pub data_frequency: Arc<AtomicF32>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new(run_impedancemeter_tx: Sender<FrequencySignal>) -> Self {
|
||||
let app = App {
|
||||
frequency: 2.0, // Default frequency
|
||||
run_impedancemeter_tx,
|
||||
magnitude: Arc::new(Mutex::new(0.0)),
|
||||
phase: Arc::new(Mutex::new(0.0)),
|
||||
@@ -34,6 +32,7 @@ impl App {
|
||||
phase_series: Arc::new(Mutex::new(TimeSeriesPlot::new())),
|
||||
connected: Arc::new(AtomicBool::new(false)),
|
||||
on: true,
|
||||
data_frequency: Arc::new(AtomicF32::new(0.0)),
|
||||
};
|
||||
app.update_start_stop();
|
||||
app
|
||||
@@ -42,7 +41,7 @@ impl App {
|
||||
pub fn update_start_stop(&self) {
|
||||
match self.on {
|
||||
true => {
|
||||
if let Err(e) = self.run_impedancemeter_tx.try_send(FrequencySignal::Start(self.frequency)) {
|
||||
if let Err(e) = self.run_impedancemeter_tx.try_send(FrequencySignal::Start(0.0)) {
|
||||
eprintln!("Failed to send start command: {:?}", e);
|
||||
}
|
||||
},
|
||||
@@ -65,11 +64,7 @@ impl eframe::App for App {
|
||||
egui::widgets::global_theme_preference_switch(ui);
|
||||
ui.separator();
|
||||
|
||||
let response = ui.add_enabled(connected, DragValue::new(&mut self.frequency).speed(0.1).update_while_editing(false).range(RangeInclusive::new(0, 50)));
|
||||
|
||||
if response.changed() && response.lost_focus() {
|
||||
self.update_start_stop();
|
||||
}
|
||||
ui.label(format!("{} Hz", self.data_frequency.load(Ordering::Relaxed)));
|
||||
|
||||
ui.separator();
|
||||
|
||||
@@ -104,7 +99,7 @@ impl eframe::App for App {
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
let available_height = ui.available_height();
|
||||
let half_height = available_height / 4.0;
|
||||
let half_height = available_height / 2.0;
|
||||
|
||||
let point_pos = vec![[*self.magnitude.lock().unwrap() as f64, *self.phase.lock().unwrap() as f64]];
|
||||
|
||||
@@ -125,7 +120,7 @@ impl eframe::App for App {
|
||||
// Magnitude and phase
|
||||
let magnitude = self.magnitude_series.lock().unwrap();
|
||||
let phase = self.phase_series.lock().unwrap();
|
||||
Plot::new("magnitude_phase")
|
||||
Plot::new("magnitude")
|
||||
.allow_scroll(false)
|
||||
.allow_drag(false)
|
||||
// .center_y_axis(true)
|
||||
@@ -133,29 +128,47 @@ impl eframe::App for App {
|
||||
.y_axis_label("Value [...]")
|
||||
.y_axis_min_width(2.0)
|
||||
.show(ui, |plot_ui| {
|
||||
|
||||
plot_ui.line(
|
||||
Line::new("Magnitude", magnitude.plot_values())
|
||||
.color(Color32::LIGHT_GREEN)
|
||||
.color(Color32::BLUE)
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
// Plot pressure
|
||||
ui.allocate_ui_with_layout(
|
||||
egui::vec2(ui.available_width(), half_height),
|
||||
Layout::top_down(egui::Align::Min),
|
||||
|ui| {
|
||||
// Magnitude and phase
|
||||
let magnitude = self.magnitude_series.lock().unwrap();
|
||||
let phase = self.phase_series.lock().unwrap();
|
||||
Plot::new("phase")
|
||||
.allow_scroll(false)
|
||||
.allow_drag(false)
|
||||
// .center_y_axis(true)
|
||||
.legend(Legend::default().position(Corner::LeftTop))
|
||||
.y_axis_label("Value [...]")
|
||||
.y_axis_min_width(2.0)
|
||||
.show(ui, |plot_ui| {
|
||||
plot_ui.line(
|
||||
Line::new("Phase", phase.plot_values())
|
||||
.color(Color32::LIGHT_RED)
|
||||
.color(Color32::RED)
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Plot::new("State")
|
||||
.allow_scroll(false)
|
||||
.allow_drag(false)
|
||||
.data_aspect(1.0)
|
||||
.center_y_axis(true)
|
||||
.show(ui, |plot_ui| {
|
||||
plot_ui.points(point_pos);
|
||||
plot_ui.set_plot_bounds(bounds);
|
||||
});
|
||||
// Plot::new("State")
|
||||
// .allow_scroll(false)
|
||||
// .allow_drag(false)
|
||||
// .data_aspect(1.0)
|
||||
// .center_y_axis(true)
|
||||
// .show(ui, |plot_ui| {
|
||||
// plot_ui.points(point_pos);
|
||||
// plot_ui.set_plot_bounds(bounds);
|
||||
// });
|
||||
});
|
||||
|
||||
// CMD- or control-W to close window
|
||||
|
||||
@@ -29,6 +29,7 @@ fn main() {
|
||||
let magnitude_series_clone = app.magnitude_series.clone();
|
||||
let phase_series_clone = app.phase_series.clone();
|
||||
let connected_clone = app.connected.clone();
|
||||
let data_frequency_clone = app.data_frequency.clone();
|
||||
|
||||
// Execute the runtime in its own thread.
|
||||
std::thread::spawn(move || {
|
||||
@@ -40,6 +41,7 @@ fn main() {
|
||||
magnitude_series_clone,
|
||||
phase_series_clone,
|
||||
connected_clone,
|
||||
data_frequency_clone,
|
||||
));
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ use log::{error, info};
|
||||
use tokio::select;
|
||||
use tokio::sync::mpsc::{Sender, Receiver};
|
||||
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
|
||||
use atomic_float::AtomicF32;
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::icd;
|
||||
@@ -21,7 +23,18 @@ pub async fn communicate_with_hardware(
|
||||
magnitude_series: Arc<Mutex<TimeSeriesPlot>>,
|
||||
phase_series: Arc<Mutex<TimeSeriesPlot>>,
|
||||
connected: Arc<AtomicBool>,
|
||||
data_frequency: Arc<AtomicF32>,
|
||||
) {
|
||||
let data_counter = Arc::new(AtomicU32::new(0));
|
||||
let data_counter_clone = data_counter.clone();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
|
||||
data_frequency.store(data_counter.load(Ordering::Relaxed) as f32, Ordering::Relaxed);
|
||||
data_counter.store(0, Ordering::Relaxed);
|
||||
}
|
||||
});
|
||||
|
||||
#[derive(Default)]
|
||||
struct Settings {
|
||||
frequency: Option<FrequencySignal>,
|
||||
@@ -52,6 +65,7 @@ pub async fn communicate_with_hardware(
|
||||
.unwrap();
|
||||
|
||||
let data = (magnitude_series.clone(), phase_series.clone(), magnitude.clone(), phase.clone());
|
||||
let data_counter_clone = data_counter_clone.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
while let Ok(val) = sub.recv().await {
|
||||
@@ -65,6 +79,8 @@ pub async fn communicate_with_hardware(
|
||||
|
||||
mag_plot.add(val.magnitude as f64);
|
||||
phase_plot.add(val.phase as f64);
|
||||
|
||||
data_counter_clone.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
info!("ImpedanceTopic subscription ended.");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user