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:
@@ -9,6 +9,7 @@ eframe = { version = "0.32.0"}
|
|||||||
egui_plot = "0.33.0"
|
egui_plot = "0.33.0"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
simple_logger = "5.0.0"
|
simple_logger = "5.0.0"
|
||||||
|
atomic_float = "1.1.0"
|
||||||
|
|
||||||
[dependencies.bioz-icd-rs]
|
[dependencies.bioz-icd-rs]
|
||||||
path = "../bioz-icd-rs"
|
path = "../bioz-icd-rs"
|
||||||
|
|||||||
61
src/app.rs
61
src/app.rs
@@ -1,8 +1,7 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use std::ops::RangeInclusive;
|
use atomic_float::AtomicF32;
|
||||||
|
|
||||||
use tokio::{sync::mpsc::{Sender}};
|
use tokio::{sync::mpsc::{Sender}};
|
||||||
|
|
||||||
use eframe::egui::{self, Color32, DragValue, Key, Layout, Modifiers, };
|
use eframe::egui::{self, Color32, DragValue, Key, Layout, Modifiers, };
|
||||||
@@ -13,7 +12,6 @@ use crate::plot::TimeSeriesPlot;
|
|||||||
use crate::signals::FrequencySignal;
|
use crate::signals::FrequencySignal;
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
frequency: f32,
|
|
||||||
run_impedancemeter_tx: Sender<FrequencySignal>,
|
run_impedancemeter_tx: Sender<FrequencySignal>,
|
||||||
pub magnitude: Arc<Mutex<f32>>,
|
pub magnitude: Arc<Mutex<f32>>,
|
||||||
pub phase: Arc<Mutex<f32>>,
|
pub phase: Arc<Mutex<f32>>,
|
||||||
@@ -21,12 +19,12 @@ pub struct App {
|
|||||||
pub phase_series: Arc<Mutex<TimeSeriesPlot>>,
|
pub phase_series: Arc<Mutex<TimeSeriesPlot>>,
|
||||||
pub connected: Arc<AtomicBool>,
|
pub connected: Arc<AtomicBool>,
|
||||||
pub on: bool,
|
pub on: bool,
|
||||||
|
pub data_frequency: Arc<AtomicF32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn new(run_impedancemeter_tx: Sender<FrequencySignal>) -> Self {
|
pub fn new(run_impedancemeter_tx: Sender<FrequencySignal>) -> Self {
|
||||||
let app = App {
|
let app = App {
|
||||||
frequency: 2.0, // Default frequency
|
|
||||||
run_impedancemeter_tx,
|
run_impedancemeter_tx,
|
||||||
magnitude: Arc::new(Mutex::new(0.0)),
|
magnitude: Arc::new(Mutex::new(0.0)),
|
||||||
phase: 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())),
|
phase_series: Arc::new(Mutex::new(TimeSeriesPlot::new())),
|
||||||
connected: Arc::new(AtomicBool::new(false)),
|
connected: Arc::new(AtomicBool::new(false)),
|
||||||
on: true,
|
on: true,
|
||||||
|
data_frequency: Arc::new(AtomicF32::new(0.0)),
|
||||||
};
|
};
|
||||||
app.update_start_stop();
|
app.update_start_stop();
|
||||||
app
|
app
|
||||||
@@ -42,7 +41,7 @@ impl App {
|
|||||||
pub fn update_start_stop(&self) {
|
pub fn update_start_stop(&self) {
|
||||||
match self.on {
|
match self.on {
|
||||||
true => {
|
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);
|
eprintln!("Failed to send start command: {:?}", e);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -65,11 +64,7 @@ impl eframe::App for App {
|
|||||||
egui::widgets::global_theme_preference_switch(ui);
|
egui::widgets::global_theme_preference_switch(ui);
|
||||||
ui.separator();
|
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)));
|
ui.label(format!("{} Hz", self.data_frequency.load(Ordering::Relaxed)));
|
||||||
|
|
||||||
if response.changed() && response.lost_focus() {
|
|
||||||
self.update_start_stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
@@ -104,7 +99,7 @@ impl eframe::App for App {
|
|||||||
|
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
let available_height = ui.available_height();
|
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]];
|
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
|
// Magnitude and phase
|
||||||
let magnitude = self.magnitude_series.lock().unwrap();
|
let magnitude = self.magnitude_series.lock().unwrap();
|
||||||
let phase = self.phase_series.lock().unwrap();
|
let phase = self.phase_series.lock().unwrap();
|
||||||
Plot::new("magnitude_phase")
|
Plot::new("magnitude")
|
||||||
.allow_scroll(false)
|
.allow_scroll(false)
|
||||||
.allow_drag(false)
|
.allow_drag(false)
|
||||||
// .center_y_axis(true)
|
// .center_y_axis(true)
|
||||||
@@ -133,29 +128,47 @@ impl eframe::App for App {
|
|||||||
.y_axis_label("Value [...]")
|
.y_axis_label("Value [...]")
|
||||||
.y_axis_min_width(2.0)
|
.y_axis_min_width(2.0)
|
||||||
.show(ui, |plot_ui| {
|
.show(ui, |plot_ui| {
|
||||||
|
|
||||||
plot_ui.line(
|
plot_ui.line(
|
||||||
Line::new("Magnitude", magnitude.plot_values())
|
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(
|
plot_ui.line(
|
||||||
Line::new("Phase", phase.plot_values())
|
Line::new("Phase", phase.plot_values())
|
||||||
.color(Color32::LIGHT_RED)
|
.color(Color32::RED)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Plot::new("State")
|
// Plot::new("State")
|
||||||
.allow_scroll(false)
|
// .allow_scroll(false)
|
||||||
.allow_drag(false)
|
// .allow_drag(false)
|
||||||
.data_aspect(1.0)
|
// .data_aspect(1.0)
|
||||||
.center_y_axis(true)
|
// .center_y_axis(true)
|
||||||
.show(ui, |plot_ui| {
|
// .show(ui, |plot_ui| {
|
||||||
plot_ui.points(point_pos);
|
// plot_ui.points(point_pos);
|
||||||
plot_ui.set_plot_bounds(bounds);
|
// plot_ui.set_plot_bounds(bounds);
|
||||||
});
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
// CMD- or control-W to close window
|
// CMD- or control-W to close window
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ fn main() {
|
|||||||
let magnitude_series_clone = app.magnitude_series.clone();
|
let magnitude_series_clone = app.magnitude_series.clone();
|
||||||
let phase_series_clone = app.phase_series.clone();
|
let phase_series_clone = app.phase_series.clone();
|
||||||
let connected_clone = app.connected.clone();
|
let connected_clone = app.connected.clone();
|
||||||
|
let data_frequency_clone = app.data_frequency.clone();
|
||||||
|
|
||||||
// Execute the runtime in its own thread.
|
// Execute the runtime in its own thread.
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
@@ -40,6 +41,7 @@ fn main() {
|
|||||||
magnitude_series_clone,
|
magnitude_series_clone,
|
||||||
phase_series_clone,
|
phase_series_clone,
|
||||||
connected_clone,
|
connected_clone,
|
||||||
|
data_frequency_clone,
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ use log::{error, info};
|
|||||||
use tokio::select;
|
use tokio::select;
|
||||||
use tokio::sync::mpsc::{Sender, Receiver};
|
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 std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use crate::icd;
|
use crate::icd;
|
||||||
@@ -21,7 +23,18 @@ pub async fn communicate_with_hardware(
|
|||||||
magnitude_series: Arc<Mutex<TimeSeriesPlot>>,
|
magnitude_series: Arc<Mutex<TimeSeriesPlot>>,
|
||||||
phase_series: Arc<Mutex<TimeSeriesPlot>>,
|
phase_series: Arc<Mutex<TimeSeriesPlot>>,
|
||||||
connected: Arc<AtomicBool>,
|
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)]
|
#[derive(Default)]
|
||||||
struct Settings {
|
struct Settings {
|
||||||
frequency: Option<FrequencySignal>,
|
frequency: Option<FrequencySignal>,
|
||||||
@@ -52,6 +65,7 @@ pub async fn communicate_with_hardware(
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let data = (magnitude_series.clone(), phase_series.clone(), magnitude.clone(), phase.clone());
|
let data = (magnitude_series.clone(), phase_series.clone(), magnitude.clone(), phase.clone());
|
||||||
|
let data_counter_clone = data_counter_clone.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
while let Ok(val) = sub.recv().await {
|
while let Ok(val) = sub.recv().await {
|
||||||
@@ -65,6 +79,8 @@ pub async fn communicate_with_hardware(
|
|||||||
|
|
||||||
mag_plot.add(val.magnitude as f64);
|
mag_plot.add(val.magnitude as f64);
|
||||||
phase_plot.add(val.phase as f64);
|
phase_plot.add(val.phase as f64);
|
||||||
|
|
||||||
|
data_counter_clone.fetch_add(1, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
info!("ImpedanceTopic subscription ended.");
|
info!("ImpedanceTopic subscription ended.");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user