use std::sync::{Arc, Mutex}; use serialport::SerialPort; mod lidar; // TODO: Should be returning results in these traits pub trait Servo { fn get_value(&self) -> f64; fn set_value(&mut self, value: f64); fn min(&mut self) { self.set_value(-1.); } fn mid(&mut self) { self.set_value(0.); } fn max(&mut self) { self.set_value(1.); } } pub trait Vehicle { fn get_throttle(&self) -> f64; fn set_throttle(&mut self, throttle: f64); fn get_steering(&self) -> f64; fn set_steering(&mut self, steering: f64); } #[cfg(feature = "rppal")] pub mod rppal { use rppal::pwm::{Channel, Pwm}; pub struct RpiPwmServo { pwm: Pwm, min_duty_cycle: f64, duty_cycle_range: f64, value: f64, frame_width: f64, } impl RpiPwmServo { pub fn new(pwm: Pwm) -> RpiPwmServo { RpiPwmServo::new(pwm, 1000000) } pub fn new(pwm: Pwm, min_pulse_width: f64) -> RpiPwmServo {} pub fn new( pwm: Pwm, min_pulse_width: f64, max_pulse_width: f64, frame_width: f64, ) -> RpiPwmServo { RpiPwmServo { pwm, min_duty_cycle: min_pulse_width / frame_width, duty_cycle_range: (max_pulse_width - min_pulse_width) / frame_width, frame_width, } } } impl Default for RpiPwmServo { fn default() -> Self { Self { pwm: Pwm::new(Channel::Pwm0).expect("Failed to initialise Pwm servo"), } } } impl Servo for RpiPwmServo { fn get_duty_cycle(&self) -> f64 { self.pwm.duty_cycle().unwrap_or(0.) } fn set_duty_cycle(&self, pwm: f64) { self.pwm .set_duty_cycle(pwm) .expect("Failed to write duty cycle"); } fn get_frequency(&self) -> f64 { self.pwm.duty_cycle().unwrap_or(0.0) } fn set_frequency(&self, frequency: f64) { self.pwm .set_frequency(frequency, self.get_duty_cycle()) .expect("Failed to set Frequency") } } } pub struct Esp32SerialPwmServo { serial_port: T, value: f64, channel: u8, pin: u8, } impl Esp32SerialPwmServo { pub fn new(serial_port: T, channel: u8, pin: u8) -> Esp32SerialPwmServo { let mut servo = Esp32SerialPwmServo { serial_port, value: 0., channel, pin, }; servo.init_pwm(); servo } } impl Esp32SerialPwmServo { fn init_pwm(&mut self) { let bytes_written = self.serial_port.write(&[0, 1, self.channel, self.pin]); // TODO: Better error handling (even anyhow would be better) match bytes_written { Ok(size) => println!("{}", size), Err(err) => eprintln!("{}", err), } } } impl Servo for Esp32SerialPwmServo { fn get_value(&self) -> f64 { self.value } fn set_value(&mut self, value: f64) { let mut temp_value = value; if temp_value < -1. { temp_value = -1.; } else if temp_value > 1. { temp_value = 1.; } self.value = temp_value; let bytes_written = self .serial_port .write(&[self.channel, ((value + 1.) / 2. * 255.) as u8]); // TODO: Better error handling match bytes_written { Ok(size) => println!("{}", size), Err(err) => eprintln!("{}", err), } } } pub struct ServoVehicle { steering_servo: T, throttle_servo: T, } impl ServoVehicle { pub fn new(steering_servo: T, throttle_servo: T) -> ServoVehicle { ServoVehicle { steering_servo, throttle_servo, } } } impl Vehicle for ServoVehicle { fn get_throttle(&self) -> f64 { self.throttle_servo.get_value() } fn set_throttle(&mut self, throttle: f64) { self.throttle_servo.set_value(throttle); } fn get_steering(&self) -> f64 { self.steering_servo.get_value() } fn set_steering(&mut self, steering: f64) { self.steering_servo.set_value(steering); } } #[derive(Default, Debug)] pub struct PrintVehicle { throttle: f64, steering: f64, } impl Vehicle for PrintVehicle { fn get_throttle(&self) -> f64 { self.throttle } fn set_throttle(&mut self, throttle: f64) { println!("New Throttle: {}", throttle); self.throttle = throttle; } fn get_steering(&self) -> f64 { self.steering } fn set_steering(&mut self, steering: f64) { println!("New Steering: {}", steering); self.steering = steering; } }