interface retries and error logging
This commit is contained in:
parent
81f55cc0e8
commit
d448f05dd7
1 changed files with 44 additions and 29 deletions
|
@ -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, ¬e) {
|
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 {
|
||||||
|
|
Loading…
Reference in a new issue