translate commands to motors
This commit is contained in:
parent
90b88607fc
commit
e58faf354f
1 changed files with 61 additions and 4 deletions
|
@ -1,16 +1,18 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::panic::PanicInfo;
|
use core::{panic::PanicInfo, sync::atomic::Ordering};
|
||||||
|
|
||||||
use common::Command;
|
use common::Command;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::{bind_interrupts, peripherals::{UART0, UART1, USB}, pwm::{self, Pwm}, uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}, usb::Driver};
|
use embassy_rp::{bind_interrupts, peripherals::{UART0, UART1, USB}, pwm::{self, Pwm}, uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config}, usb::Driver};
|
||||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel};
|
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{with_deadline, with_timeout, Duration, Instant, Timer};
|
||||||
use embedded_io_async::{BufRead, Read};
|
use embedded_io_async::{BufRead, Read};
|
||||||
use framed::{bytes, FRAME_END_SYMBOL};
|
use framed::{bytes, FRAME_END_SYMBOL};
|
||||||
use log::{error, info, warn};
|
use log::{error, info, trace, warn};
|
||||||
|
use nalgebra::clamp;
|
||||||
|
use portable_atomic::AtomicBool;
|
||||||
use static_cell::{ConstStaticCell, StaticCell};
|
use static_cell::{ConstStaticCell, StaticCell};
|
||||||
|
|
||||||
bind_interrupts!(struct Irqs {
|
bind_interrupts!(struct Irqs {
|
||||||
|
@ -23,7 +25,7 @@ pub static COMMANDS: Channel<CriticalSectionRawMutex, Command, 5> = Channel::new
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn logger_task(driver: Driver<'static, USB>) {
|
async fn logger_task(driver: Driver<'static, USB>) {
|
||||||
embassy_usb_logger::run!(1024, log::LevelFilter::Debug, driver);
|
embassy_usb_logger::run!(1024, log::LevelFilter::Trace, driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
|
@ -44,6 +46,7 @@ async fn main(spawner: Spawner) {
|
||||||
drive_conf.top = 62500; // 20ms
|
drive_conf.top = 62500; // 20ms
|
||||||
drive_conf.compare_b = 4687; // 1.5ms
|
drive_conf.compare_b = 4687; // 1.5ms
|
||||||
drive_conf.compare_a = 4687; // 1.5ms
|
drive_conf.compare_a = 4687; // 1.5ms
|
||||||
|
let stopped = drive_conf.clone();
|
||||||
let mut drive_pwm = Pwm::new_output_ab(p.PWM_SLICE0, p.PIN_16, p.PIN_17, drive_conf.clone());
|
let mut drive_pwm = Pwm::new_output_ab(p.PWM_SLICE0, p.PIN_16, p.PIN_17, drive_conf.clone());
|
||||||
|
|
||||||
let config = embassy_rp::i2c::Config::default();
|
let config = embassy_rp::i2c::Config::default();
|
||||||
|
@ -60,8 +63,50 @@ async fn main(spawner: Spawner) {
|
||||||
|
|
||||||
spawner.spawn(decoder(rx)).unwrap();
|
spawner.spawn(decoder(rx)).unwrap();
|
||||||
|
|
||||||
|
let enabled = AtomicBool::new(false);
|
||||||
|
let mut enable_watchdog = Instant::now();
|
||||||
|
let enable_watchdog_time = Duration::from_millis(50);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
if !enabled.load(Ordering::Acquire) {
|
||||||
|
// stop all motors
|
||||||
|
drive_pwm.set_config(&stopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
let command = if enabled.load(Ordering::Acquire) {
|
||||||
|
let Ok(command) = with_deadline(enable_watchdog + enable_watchdog_time, COMMANDS.receive()).await else {
|
||||||
|
warn!("no message received");
|
||||||
|
enabled.store(false, Ordering::Release);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
command
|
||||||
|
} else {
|
||||||
|
COMMANDS.receive().await
|
||||||
|
};
|
||||||
|
|
||||||
|
match command {
|
||||||
|
Command::Twist(forward, right) => {
|
||||||
|
drive_conf.compare_a = calc_speed(forward - right);
|
||||||
|
drive_conf.compare_b = calc_speed(forward + right);
|
||||||
|
drive_pwm.set_config(&drive_conf);
|
||||||
|
},
|
||||||
|
Command::Stop => {
|
||||||
|
drive_pwm.set_config(&stopped);
|
||||||
|
},
|
||||||
|
Command::Enable => {
|
||||||
|
enabled.store(true, Ordering::Release);
|
||||||
|
enable_watchdog = Instant::now();
|
||||||
|
},
|
||||||
|
Command::Disable => {
|
||||||
|
enabled.store(false, Ordering::Release);
|
||||||
|
drive_pwm.set_config(&stopped);
|
||||||
|
},
|
||||||
|
Command::FeedWatchdog => {
|
||||||
|
enable_watchdog = Instant::now();
|
||||||
|
}
|
||||||
|
c => { error!("{c:?} unimplemented") }
|
||||||
|
};
|
||||||
|
|
||||||
info!("Blink");
|
info!("Blink");
|
||||||
Timer::after(Duration::from_millis(100)).await;
|
Timer::after(Duration::from_millis(100)).await;
|
||||||
}
|
}
|
||||||
|
@ -89,8 +134,20 @@ async fn decoder(mut rx: BufferedUartRx<'static, UART1>) {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
trace!("received {data:?}");
|
||||||
|
|
||||||
COMMANDS.send(data).await;
|
COMMANDS.send(data).await;
|
||||||
|
|
||||||
rx.consume(end);
|
rx.consume(end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// -1 to 1
|
||||||
|
fn calc_speed(speed: f32) -> u16 {
|
||||||
|
const COUNTS_PER_MS: f32 = 3125.;
|
||||||
|
let speed = speed.clamp(-1., 1.);
|
||||||
|
|
||||||
|
let ms = (speed/2.0)+1.5;
|
||||||
|
|
||||||
|
(COUNTS_PER_MS * ms) as u16
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue