diff --git a/red/src/jogger.rs b/red/src/gamepad.rs similarity index 50% rename from red/src/jogger.rs rename to red/src/gamepad.rs index 57fb39b..d410ce5 100644 --- a/red/src/jogger.rs +++ b/red/src/gamepad.rs @@ -17,21 +17,39 @@ pub enum Axis { } #[derive(Debug)] -pub enum ControllerEvent { +pub enum GamepadEvent { AxisPosition(Axis, f32), TerminatePressed, } -pub struct Jogger { +/// Read inputs from connected gamepads and translate those to commands for the Machine +/// +/// Example: +/// ```rust +/// +/// let jogger = jogger::Jogger::new().await.unwrap(); +/// loop { +/// tokio::time::sleep(Duration::from_secs(2)).await; +/// let setpoint = jogger.speed_setpoint(); +/// println!( +/// "speed setpoint: {} {} {}", +/// setpoint.0, setpoint.1, setpoint.2 +/// ); +/// } +/// ``` +pub struct Gamepad { speed_setpoint: Mutex<(f32, f32, f32)>, terminator: oneshot::Sender<()>, } -impl Jogger { +impl Gamepad { + /// Create a new `Gamepad` and spawn the underlying tasks for updating internal setpoints + /// + /// The tasks are terminated on drop. pub async fn new() -> Result, gilrs::Error> { let (terminate_tx, mut terminate_rx) = oneshot::channel(); - let (controller_tx, controller_rx) = mpsc::channel(8); - let res = Arc::new(Jogger { + let (gamepad_tx, gamepad_rx) = mpsc::channel(8); + let res = Arc::new(Gamepad { speed_setpoint: Mutex::new((0.0, 0.0, 0.0)), terminator: terminate_tx, }); @@ -43,27 +61,29 @@ impl Jogger { while let Err(oneshot::error::TryRecvError::Empty) = terminate_rx.try_recv() { sleep(Duration::from_millis(1)); if let Some(event) = gilrs.next_event() { - Self::map_event(event).map(|event| controller_tx.blocking_send(event)); + Self::map_event(event).map(|event| gamepad_tx.blocking_send(event)); } } }); - tokio::spawn(Self::handle_events(res.clone(), controller_rx)); + tokio::spawn(Self::handle_events(res.clone(), gamepad_rx)); Ok(res) } - pub fn speed_setpoint(&self) -> (f32, f32, f32){ + /// Get the current speed that the user is dialing in on the gamepad + pub fn speed_setpoint(&self) -> (f32, f32, f32) { *self.speed_setpoint.lock().unwrap() } - async fn handle_events(self_arc: Arc, mut events_rx: mpsc::Receiver) { + /// Update the setpoints in accordance to incoming `GamepadEvent`s + async fn handle_events(self_arc: Arc, mut events_rx: mpsc::Receiver) { let mut z_positive = 0.0; let mut z_negative = 0.0; while let Some(event) = events_rx.recv().await { match event { - ControllerEvent::TerminatePressed => break, - ControllerEvent::AxisPosition(axis, value) => { + GamepadEvent::TerminatePressed => break, + GamepadEvent::AxisPosition(axis, value) => { // I won't panic if you don't panic! let mut speed_setpoint = self_arc.speed_setpoint.lock().unwrap(); match axis { @@ -71,34 +91,32 @@ impl Jogger { Axis::Y => speed_setpoint.1 = value, Axis::ZPositive => { z_positive = value; - speed_setpoint.2 = z_positive-z_negative; + speed_setpoint.2 = z_positive - z_negative; } Axis::ZNegative => { z_negative = value; - speed_setpoint.2 = z_positive-z_negative; + speed_setpoint.2 = z_positive - z_negative; } } } } } - println!("Controller quit!") + println!("Game pad quit!") } - fn map_event(event: gilrs::Event) -> Option { + fn map_event(event: gilrs::Event) -> Option { match event.event { - AxisChanged(LeftStickX, value, _) => { - Some(ControllerEvent::AxisPosition(Axis::X, value)) - } - AxisChanged(LeftStickY, value, _) => { - Some(ControllerEvent::AxisPosition(Axis::Y, value)) - } - AxisChanged(RightZ, value, _) => { - Some(ControllerEvent::AxisPosition(Axis::ZNegative, (1.0+value)/2.0)) - } - AxisChanged(LeftZ, value, _) => { - Some(ControllerEvent::AxisPosition(Axis::ZPositive, (1.0+value)/2.0)) - } - ButtonPressed(gilrs::Button::Start, _) => Some(ControllerEvent::TerminatePressed), + AxisChanged(LeftStickX, value, _) => Some(GamepadEvent::AxisPosition(Axis::X, value)), + AxisChanged(LeftStickY, value, _) => Some(GamepadEvent::AxisPosition(Axis::Y, value)), + AxisChanged(RightZ, value, _) => Some(GamepadEvent::AxisPosition( + Axis::ZNegative, + (1.0 + value) / 2.0, + )), + AxisChanged(LeftZ, value, _) => Some(GamepadEvent::AxisPosition( + Axis::ZPositive, + (1.0 + value) / 2.0, + )), + ButtonPressed(gilrs::Button::Start, _) => Some(GamepadEvent::TerminatePressed), _ => None, } } diff --git a/red/src/lib.rs b/red/src/lib.rs index dc85e2d..2e00e3b 100644 --- a/red/src/lib.rs +++ b/red/src/lib.rs @@ -1,2 +1,2 @@ +pub mod gamepad; pub mod printer; -pub mod jogger; diff --git a/red/src/main.rs b/red/src/main.rs index 451e5e1..2777cba 100644 --- a/red/src/main.rs +++ b/red/src/main.rs @@ -1,7 +1,7 @@ #![warn(rust_2018_idioms)] use futures::never::Never; use i2c_linux::I2c; -use red::jogger; +use red::gamepad; use red::printer::gcode::*; use red::printer::Printer; use std::time::Duration; @@ -33,7 +33,7 @@ const I2C_REGISTER_SPINDLE_SPEED: u8 = 0; #[tokio::main] async fn main() -> Never { - write_to_spindle().await + jog().await } async fn write_to_spindle() -> Never { @@ -89,7 +89,7 @@ async fn write_to_printer() -> Never { } async fn jog() -> Never { - let jogger = jogger::Jogger::new().await.unwrap(); + let jogger = gamepad::Gamepad::new().await.unwrap(); loop { tokio::time::sleep(Duration::from_secs(2)).await; let setpoint = jogger.speed_setpoint();