1
Fork 0

interface retries and error logging

This commit is contained in:
Andy Killorin 2025-03-08 08:32:03 -05:00
parent 81f55cc0e8
commit d448f05dd7
Signed by: ank
GPG key ID: 23F9463ECB67FE8C

View file

@ -1,5 +1,5 @@
#![feature(iter_collect_into)] #![feature(iter_collect_into)]
use std::{ops::ControlFlow, result, sync::Arc, thread::{self, sleep}, time::Duration}; use std::{fmt::format, ops::ControlFlow, result, sync::Arc, thread::{self, sleep}, time::Duration};
use anyhow::{Context, Ok, Result}; use anyhow::{Context, Ok, Result};
use common::{ControlPacket, TelemetryPacket}; use common::{ControlPacket, TelemetryPacket};
@ -8,7 +8,7 @@ use egui_toast::{Toast, ToastKind};
use gui::{gui, GUIData, GUI}; use gui::{gui, GUIData, GUI};
use pitch_detection::{detector::{mcleod::McLeodDetector, PitchDetector}, utils}; use pitch_detection::{detector::{mcleod::McLeodDetector, PitchDetector}, utils};
use rust_music_theory::note::{Note, NoteLetter, Pitch, Tuning}; use rust_music_theory::note::{Note, NoteLetter, Pitch, Tuning};
use tokio::{io::{AsyncReadExt, AsyncWriteExt, BufWriter, WriteHalf}, net::{tcp::{OwnedReadHalf, OwnedWriteHalf}, TcpStream}, spawn, sync::{self, mpsc, watch, RwLock}, time::timeout}; use tokio::{io::{AsyncReadExt, AsyncWriteExt, BufWriter, WriteHalf}, net::{tcp::{OwnedReadHalf, OwnedWriteHalf}, TcpStream}, spawn, sync::{self, broadcast, mpsc, watch, RwLock}, time::timeout};
mod gui; mod gui;
@ -29,7 +29,7 @@ fn main() -> Result<()> {
dbg!(config.sample_format()); dbg!(config.sample_format());
let rate = config.sample_rate(); let rate = config.sample_rate();
let (sender, notes) = mpsc::channel(2); let (sender, notes) = broadcast::channel(2);
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
const POWER_THRESHOLD: f32 = 5.0; const POWER_THRESHOLD: f32 = 5.0;
@ -65,7 +65,9 @@ fn main() -> Result<()> {
// reinitialized every packet as it is not thread safe // reinitialized every packet as it is not thread safe
let mut detctor = McLeodDetector::new(PACKET_LEN, PACKET_LEN/2); let mut detctor = McLeodDetector::new(PACKET_LEN, PACKET_LEN/2);
let vol = utils::buffer::square_sum(data); let vol = utils::buffer::square_sum(data);
sender.blocking_send((detctor.get_pitch(data, rate.0 as usize, POWER_THRESHOLD, CLARITY_THRESHOLD),vol)).unwrap(); if let Err(e) = sender.send((detctor.get_pitch(data, rate.0 as usize, POWER_THRESHOLD, CLARITY_THRESHOLD).map(|p|p.frequency),vol)) {
println!("channel: {e}");
}
}, },
move |err| {eprintln!("{err}")} , move |err| {eprintln!("{err}")} ,
@ -83,20 +85,16 @@ fn main() -> Result<()> {
let spawner = executor.handle().clone(); let spawner = executor.handle().clone();
thread::spawn(move || { thread::spawn(move || {
let control = spawner.block_on(async { spawner.block_on(async {
toast_sender.send(Toast::new().text("connecting to bot").kind(ToastKind::Info)).await.unwrap(); loop {
let cruisecontrol = TcpStream::connect("192.168.1.2:1234").await?; if let Err(e) = connect(toast_sender.clone(), notes.resubscribe(), data_sender.clone()).await {
println!("connected"); if let Err(_) = toast_sender.send(Toast::new().text(format!("{e:?}")).kind(ToastKind::Error)).await {
toast_sender.send(Toast::new().text("connected").kind(ToastKind::Success)).await.unwrap(); break;
cruisecontrol.set_nodelay(true)?; };
let (telem, control) = cruisecontrol.into_split(); }
}
});
tokio::spawn(telemetry_handler(telem, data_sender.clone()));
Ok(control)
}).unwrap();
spawner.block_on(controller(notes, control, data_sender.clone())).unwrap()
}); });
println!("launching gui"); println!("launching gui");
@ -107,6 +105,23 @@ fn main() -> Result<()> {
Ok(()) Ok(())
} }
/// frequency, volume
type Detection = (Option<f32>, f32);
async fn connect(toast_sender: mpsc::Sender<Toast>, notes: broadcast::Receiver<Detection>, data_sender: watch::Sender<GUIData>) -> Result<()>{
toast_sender.send(Toast::new().text("connecting to bot").kind(ToastKind::Info)).await?;
let cruisecontrol = TcpStream::connect("192.168.1.2:1234").await?;
println!("connected");
toast_sender.send(Toast::new().text("connected").kind(ToastKind::Success)).await?;
cruisecontrol.set_nodelay(true)?;
let (telem, control) = cruisecontrol.into_split();
tokio::spawn(telemetry_handler(telem, data_sender.clone()));
controller(notes, control, data_sender.clone()).await?;
Ok(())
}
async fn telemetry_handler(mut telem: OwnedReadHalf, gui: watch::Sender<GUIData>) -> Result<()> { async fn telemetry_handler(mut telem: OwnedReadHalf, gui: watch::Sender<GUIData>) -> Result<()> {
let mut buf = vec![0; 2048]; let mut buf = vec![0; 2048];
loop { loop {
@ -115,7 +130,7 @@ async fn telemetry_handler(mut telem: OwnedReadHalf, gui: watch::Sender<GUIData>
telem.read_exact(data).await?; telem.read_exact(data).await?;
let telem: TelemetryPacket = postcard::from_bytes(&data)?; let telem: TelemetryPacket = postcard::from_bytes(&data)?;
println!("telem: {telem:?}"); //println!("telem: {telem:?}");
gui.send_modify(|gui| { gui.send_modify(|gui| {
gui.telemetry = Some(telem); gui.telemetry = Some(telem);
@ -124,7 +139,7 @@ async fn telemetry_handler(mut telem: OwnedReadHalf, gui: watch::Sender<GUIData>
} }
} }
async fn controller(mut notes: mpsc::Receiver<(Option<pitch_detection::Pitch<f32>>, f32)>, controller: OwnedWriteHalf, gui: watch::Sender<GUIData>) -> Result<()> { async fn controller(mut notes: broadcast::Receiver<Detection>, controller: OwnedWriteHalf, gui: watch::Sender<GUIData>) -> Result<()> {
let mut controller = BufWriter::new(controller); let mut controller = BufWriter::new(controller);
//send_packet(&mut controller, ControlPacket::Arm(true)).await?; //send_packet(&mut controller, ControlPacket::Arm(true)).await?;
//println!("armed flipper"); //println!("armed flipper");
@ -145,8 +160,8 @@ async fn controller(mut notes: mpsc::Receiver<(Option<pitch_detection::Pitch<f32
let (note,vol) = note.context("channel closed")?; let (note,vol) = note.context("channel closed")?;
if let Some(note) = note { if let Some(note) = note {
dbg!(note.frequency); dbg!(note);
if let ControlFlow::Break(_) = sax_control(&mut control, vol, &note) { if let ControlFlow::Break(_) = sax_control(&mut control, vol, note) {
if let ControlFlow::Break(_) = recorder_control(&mut control, vol, note) { if let ControlFlow::Break(_) = recorder_control(&mut control, vol, note) {
continue; continue;
} }
@ -165,16 +180,16 @@ async fn controller(mut notes: mpsc::Receiver<(Option<pitch_detection::Pitch<f32
/// Weapon enabled /// Weapon enabled
const ARMED: bool = true; const ARMED: bool = true;
fn sax_control(control: &mut ControlPacket, vol: f32, note: &pitch_detection::Pitch<f32>) -> ControlFlow<()> { fn sax_control(control: &mut ControlPacket, vol: f32, frequency: f32) -> ControlFlow<()> {
if note.frequency < 150. { if frequency < 150. {
println!("too low"); println!("too low");
return ControlFlow::Break(()); return ControlFlow::Break(());
} }
if note.frequency > 270. { if frequency > 270. {
println!("too high"); println!("too high");
return ControlFlow::Break(()); return ControlFlow::Break(());
} }
let note = Note::from_freq(note.frequency, Tuning::EqualTemperament); let note = Note::from_freq(frequency, Tuning::EqualTemperament);
//dbg!(note.clarity); //dbg!(note.clarity);
//dbg!(vol); //dbg!(vol);
match note.pitch { match note.pitch {
@ -218,16 +233,16 @@ fn sax_control(control: &mut ControlPacket, vol: f32, note: &pitch_detection::Pi
} }
fn recorder_control(control: &mut ControlPacket, vol: f32, note: pitch_detection::Pitch<f32>) -> ControlFlow<()> { fn recorder_control(control: &mut ControlPacket, vol: f32, frequency: f32) -> ControlFlow<()> {
if note.frequency < 300. { if frequency < 300. {
println!("too low"); println!("too low");
return ControlFlow::Break(()); return ControlFlow::Break(());
} }
if note.frequency > 600. { if frequency > 600. {
println!("too high"); println!("too high");
return ControlFlow::Break(()); return ControlFlow::Break(());
} }
let note = Note::from_freq(note.frequency, Tuning::EqualTemperament); let note = Note::from_freq(frequency, Tuning::EqualTemperament);
//dbg!(note.clarity); //dbg!(note.clarity);
//dbg!(vol); //dbg!(vol);
match note.pitch { match note.pitch {