1
Fork 0

plumb auto interface into controller

This commit is contained in:
Andy Killorin 2025-03-27 19:25:39 -04:00
parent b956c543fc
commit 311427b0a5
Signed by: ank
GPG key ID: 23F9463ECB67FE8C
4 changed files with 31 additions and 13 deletions

View file

@ -25,7 +25,7 @@ pub enum ControlPacket {
EStop,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
pub struct SensorData {
/// left distance, mm
pub tof_l: Option<u16>,
@ -45,6 +45,12 @@ pub struct TelemetryPacket {
pub cam_state: CamState,
}
impl Default for TelemetryPacket {
fn default() -> Self {
Self { sensors: Default::default(), cam_state: CamState::Idle }
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum CamState {
Firing,

View file

@ -89,7 +89,7 @@ async fn main(spawner: Spawner) {
spawner.spawn(logger_task(driver)).unwrap();
let limit_switch = Input::new(p.PIN_16, Pull::Up);
let mut auto_status = Output::new(p.PIN_2, Level::Low);
let mut auto_status = Output::new(p.PIN_2, Level::High);
let mut d: pwm::Config = Default::default();
d.divider = 40.into();

View file

@ -17,7 +17,7 @@ pub struct AutoInterface {
}
impl AutoInterface {
pub(crate) fn new(data: watch::Receiver<TelemetryPacket>, config: StorageManager, enable_permission: Arc<AtomicBool>) -> (Self, watch::Receiver<ControlPacket>) {
pub fn new(data: watch::Receiver<TelemetryPacket>, config: StorageManager, enable_permission: Arc<AtomicBool>) -> (Self, watch::Receiver<ControlPacket>) {
let (commands, receiver) = watch::channel(ControlPacket::Fire);
let interface = Self {
@ -30,6 +30,11 @@ impl AutoInterface {
(interface, receiver)
}
pub fn subscribe(&self) -> watch::Receiver<ControlPacket> {
self.command_sender.subscribe()
}
/// change active command, fails if not in control
pub fn run_command(&self, command: ControlPacket) -> Result<()> {
self.command_sender.send(command)?;

View file

@ -1,9 +1,9 @@
use std::{fmt::format, ops::ControlFlow, path::Path, result, sync::{atomic::Ordering, Arc}, thread::{self, sleep}, time::Duration};
use std::{fmt::format, ops::ControlFlow, path::Path, result, sync::{atomic::{AtomicBool, Ordering}, Arc}, thread::{self, sleep}, time::Duration};
use anyhow::{Context, Ok, Result};
use atomic_float::AtomicF32;
use directories::ProjectDirs;
use interface::{auto::{get_confs, Auto}, combatlog::{combat_logger, CombatData}, gui::CONFIGS, storage::StorageManager, POWER_THRESHOLD};
use interface::{auto::{get_confs, Auto, AutoInterface}, combatlog::{combat_logger, CombatData}, gui::CONFIGS, storage::StorageManager, POWER_THRESHOLD};
use common::{ControlPacket, TelemetryPacket};
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use egui_toast::{Toast, ToastKind};
@ -19,6 +19,11 @@ fn main() -> Result<()> {
let storage = StorageManager::new(directories.config_dir().to_path_buf().join(Path::new("conf.dat")))?;
let auto_allowed = Arc::new(AtomicBool::new(false));
let (auto_telem_sender, auto_telem) = watch::channel(TelemetryPacket::default());
let (interface, auto_command) = AutoInterface::new(auto_telem.clone(), storage.clone(), auto_allowed.clone());
println!("name: {}", auto.name());
for config in auto.configs().iter() {
@ -104,7 +109,7 @@ fn main() -> Result<()> {
});
loop {
if let Err(e) = connect(toast_sender.clone(), notes.resubscribe(), data_sender.clone(), logging_sender.clone()).await {
if let Err(e) = connect(toast_sender.clone(), notes.resubscribe(), data_sender.clone(), logging_sender.clone(), auto_telem_sender.clone(), auto_allowed.clone(), interface.clone()).await {
if let Err(_) = toast_sender.send(Toast::new().text(format!("{e:?}")).kind(ToastKind::Error)).await {
break;
};
@ -128,7 +133,7 @@ fn main() -> Result<()> {
/// frequency, volume
type Detection = (Option<f32>, f32);
async fn connect(toast_sender: mpsc::Sender<Toast>, notes: broadcast::Receiver<Detection>, data_sender: watch::Sender<GUIData>, logging_sender: mpsc::Sender<CombatData>) -> Result<()>{
async fn connect(toast_sender: mpsc::Sender<Toast>, notes: broadcast::Receiver<Detection>, data_sender: watch::Sender<GUIData>, logging_sender: mpsc::Sender<CombatData>, auto_sender: watch::Sender<TelemetryPacket>, auto_allowed: Arc<AtomicBool>, interface: AutoInterface) -> 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");
@ -136,13 +141,13 @@ async fn connect(toast_sender: mpsc::Sender<Toast>, notes: broadcast::Receiver<D
cruisecontrol.set_nodelay(true)?;
let (telem, control) = cruisecontrol.into_split();
tokio::spawn(telemetry_handler(telem, data_sender.clone(), logging_sender.clone()));
tokio::spawn(telemetry_handler(telem, data_sender.clone(), logging_sender.clone(), auto_sender.clone()));
controller(notes, control, data_sender.clone(), logging_sender.clone()).await?;
controller(notes, control, data_sender.clone(), logging_sender.clone(), auto_allowed, interface).await?;
Ok(())
}
async fn telemetry_handler(mut telem: OwnedReadHalf, gui: watch::Sender<GUIData>, logging_sender: mpsc::Sender<CombatData>) -> Result<()> {
async fn telemetry_handler(mut telem: OwnedReadHalf, gui: watch::Sender<GUIData>, logging_sender: mpsc::Sender<CombatData>, auto_sender: watch::Sender<TelemetryPacket>) -> Result<()> {
let mut buf = vec![0; 2048];
loop {
let len = telem.read_u32().await.context("bad length")? as usize;
@ -152,7 +157,8 @@ async fn telemetry_handler(mut telem: OwnedReadHalf, gui: watch::Sender<GUIData>
//println!("telem: {telem:?}");
logging_sender.send(CombatData::Telemetry(telem.clone())).await?;
auto_sender.send(telem.clone())?;
let _ = logging_sender.send(CombatData::Telemetry(telem.clone())).await;
gui.send_modify(|gui| {
gui.telemetry = Some(telem);
@ -161,7 +167,7 @@ async fn telemetry_handler(mut telem: OwnedReadHalf, gui: watch::Sender<GUIData>
}
}
async fn controller(mut notes: broadcast::Receiver<Detection>, controller: OwnedWriteHalf, gui: watch::Sender<GUIData>, logging_sender: mpsc::Sender<CombatData>) -> Result<()> {
async fn controller(mut notes: broadcast::Receiver<Detection>, controller: OwnedWriteHalf, gui: watch::Sender<GUIData>, logging_sender: mpsc::Sender<CombatData>, enable: Arc<AtomicBool>, interface: AutoInterface) -> Result<()> {
let mut controller = BufWriter::new(controller);
//send_packet(&mut controller, ControlPacket::Arm(true)).await?;
//println!("armed flipper");
@ -171,6 +177,7 @@ async fn controller(mut notes: broadcast::Receiver<Detection>, controller: Owned
//auto = Some(spawn(seek))
loop {
let mut control = ControlPacket::Stop;
@ -190,7 +197,7 @@ async fn controller(mut notes: broadcast::Receiver<Detection>, controller: Owned
}
send_packet(&mut controller, control.clone()).await?;
logging_sender.send(CombatData::Control(control.clone())).await?;
let _ = logging_sender.send(CombatData::Control(control.clone())).await;
gui.send_modify(|gui| gui.last_command = Some(control));
} else {
send_packet(&mut controller, ControlPacket::Twist(0.0, 0.0)).await?;