Rename jogger to gamepad

This commit is contained in:
Frederik Menke 2023-11-18 14:50:41 +01:00
parent 00ada18db5
commit 19decf59bd
3 changed files with 50 additions and 32 deletions

View file

@ -17,21 +17,39 @@ pub enum Axis {
} }
#[derive(Debug)] #[derive(Debug)]
pub enum ControllerEvent { pub enum GamepadEvent {
AxisPosition(Axis, f32), AxisPosition(Axis, f32),
TerminatePressed, 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)>, speed_setpoint: Mutex<(f32, f32, f32)>,
terminator: oneshot::Sender<()>, 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<Arc<Self>, gilrs::Error> { pub async fn new() -> Result<Arc<Self>, gilrs::Error> {
let (terminate_tx, mut terminate_rx) = oneshot::channel(); let (terminate_tx, mut terminate_rx) = oneshot::channel();
let (controller_tx, controller_rx) = mpsc::channel(8); let (gamepad_tx, gamepad_rx) = mpsc::channel(8);
let res = Arc::new(Jogger { let res = Arc::new(Gamepad {
speed_setpoint: Mutex::new((0.0, 0.0, 0.0)), speed_setpoint: Mutex::new((0.0, 0.0, 0.0)),
terminator: terminate_tx, terminator: terminate_tx,
}); });
@ -43,27 +61,29 @@ impl Jogger {
while let Err(oneshot::error::TryRecvError::Empty) = terminate_rx.try_recv() { while let Err(oneshot::error::TryRecvError::Empty) = terminate_rx.try_recv() {
sleep(Duration::from_millis(1)); sleep(Duration::from_millis(1));
if let Some(event) = gilrs.next_event() { 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) 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() *self.speed_setpoint.lock().unwrap()
} }
async fn handle_events(self_arc: Arc<Self>, mut events_rx: mpsc::Receiver<ControllerEvent>) { /// Update the setpoints in accordance to incoming `GamepadEvent`s
async fn handle_events(self_arc: Arc<Self>, mut events_rx: mpsc::Receiver<GamepadEvent>) {
let mut z_positive = 0.0; let mut z_positive = 0.0;
let mut z_negative = 0.0; let mut z_negative = 0.0;
while let Some(event) = events_rx.recv().await { while let Some(event) = events_rx.recv().await {
match event { match event {
ControllerEvent::TerminatePressed => break, GamepadEvent::TerminatePressed => break,
ControllerEvent::AxisPosition(axis, value) => { GamepadEvent::AxisPosition(axis, value) => {
// I won't panic if you don't panic! // I won't panic if you don't panic!
let mut speed_setpoint = self_arc.speed_setpoint.lock().unwrap(); let mut speed_setpoint = self_arc.speed_setpoint.lock().unwrap();
match axis { match axis {
@ -71,34 +91,32 @@ impl Jogger {
Axis::Y => speed_setpoint.1 = value, Axis::Y => speed_setpoint.1 = value,
Axis::ZPositive => { Axis::ZPositive => {
z_positive = value; z_positive = value;
speed_setpoint.2 = z_positive-z_negative; speed_setpoint.2 = z_positive - z_negative;
} }
Axis::ZNegative => { Axis::ZNegative => {
z_negative = value; 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<ControllerEvent> { fn map_event(event: gilrs::Event) -> Option<GamepadEvent> {
match event.event { match event.event {
AxisChanged(LeftStickX, value, _) => { AxisChanged(LeftStickX, value, _) => Some(GamepadEvent::AxisPosition(Axis::X, value)),
Some(ControllerEvent::AxisPosition(Axis::X, value)) AxisChanged(LeftStickY, value, _) => Some(GamepadEvent::AxisPosition(Axis::Y, value)),
} AxisChanged(RightZ, value, _) => Some(GamepadEvent::AxisPosition(
AxisChanged(LeftStickY, value, _) => { Axis::ZNegative,
Some(ControllerEvent::AxisPosition(Axis::Y, value)) (1.0 + value) / 2.0,
} )),
AxisChanged(RightZ, value, _) => { AxisChanged(LeftZ, value, _) => Some(GamepadEvent::AxisPosition(
Some(ControllerEvent::AxisPosition(Axis::ZNegative, (1.0+value)/2.0)) Axis::ZPositive,
} (1.0 + value) / 2.0,
AxisChanged(LeftZ, value, _) => { )),
Some(ControllerEvent::AxisPosition(Axis::ZPositive, (1.0+value)/2.0)) ButtonPressed(gilrs::Button::Start, _) => Some(GamepadEvent::TerminatePressed),
}
ButtonPressed(gilrs::Button::Start, _) => Some(ControllerEvent::TerminatePressed),
_ => None, _ => None,
} }
} }

View file

@ -1,2 +1,2 @@
pub mod gamepad;
pub mod printer; pub mod printer;
pub mod jogger;

View file

@ -1,7 +1,7 @@
#![warn(rust_2018_idioms)] #![warn(rust_2018_idioms)]
use futures::never::Never; use futures::never::Never;
use i2c_linux::I2c; use i2c_linux::I2c;
use red::jogger; use red::gamepad;
use red::printer::gcode::*; use red::printer::gcode::*;
use red::printer::Printer; use red::printer::Printer;
use std::time::Duration; use std::time::Duration;
@ -33,7 +33,7 @@ const I2C_REGISTER_SPINDLE_SPEED: u8 = 0;
#[tokio::main] #[tokio::main]
async fn main() -> Never { async fn main() -> Never {
write_to_spindle().await jog().await
} }
async fn write_to_spindle() -> Never { async fn write_to_spindle() -> Never {
@ -89,7 +89,7 @@ async fn write_to_printer() -> Never {
} }
async fn jog() -> Never { async fn jog() -> Never {
let jogger = jogger::Jogger::new().await.unwrap(); let jogger = gamepad::Gamepad::new().await.unwrap();
loop { loop {
tokio::time::sleep(Duration::from_secs(2)).await; tokio::time::sleep(Duration::from_secs(2)).await;
let setpoint = jogger.speed_setpoint(); let setpoint = jogger.speed_setpoint();