mod algorithm;
pub mod control;
const LOOPRATE: Duration = Duration::from_millis(10);
use std::time::Duration;
use control::PursuitControl;
use vexide::time::sleep;
use crate::{
motion::{
localization::{Localizer, tracker::Tracker},
pursuit::algorithm::abs_arc_point,
},
peripherals::drivetrain::Differential,
utils::{geo, geo::Pose, units::Length},
};
#[derive(Debug, Clone, Copy)]
pub struct Pursuit {
pub lookahead: Length,
}
impl Pursuit {
pub fn new(lookahead: Length) -> Self { Self { lookahead } }
pub async fn follow<C: PursuitControl>(
&self,
odom: &mut Tracker,
drivetrain: &Differential,
ctrl_algorithm: &C,
path: geo::Path,
) {
let mut run = true;
while run {
let odometry_values = odom.get_coords();
let (x, y, t) = (odometry_values.x, odometry_values.y, odometry_values.t);
let cir = geo::Circle {
x: x.as_inches(),
y: y.as_inches(),
r: self.lookahead.as_inches(),
};
let target = algorithm::pursuit_target(path.clone(), cir);
let (tarx, tary) = abs_arc_point(
Pose::new(x, y, t),
Length::as_inches(Length::from_inches(target.x)),
Length::as_inches(Length::from_inches(target.y)),
);
let ((powl, powr), run_curr) = ctrl_algorithm.control(
Length::from_inches(tarx),
Length::from_inches(tary),
self.lookahead,
);
drivetrain.set_left_voltage(powl);
drivetrain.set_right_voltage(powr);
run = run_curr;
odom.tick().await;
sleep(LOOPRATE).await;
}
}
pub async fn tick<C: PursuitControl>(
&self,
odom: &mut Tracker,
drivetrain: &Differential,
ctrl_algorithm: &C,
path: geo::Path,
) -> bool {
let odometry_values = odom.get_coords();
let (x, y, t) = (odometry_values.x, odometry_values.y, odometry_values.t);
let cir = geo::Circle {
x: x.as_inches(),
y: y.as_inches(),
r: self.lookahead.as_inches(),
};
let target = algorithm::pursuit_target(path.clone(), cir);
let (tarx, tary) = abs_arc_point(
Pose::new(x, y, t),
Length::as_inches(Length::from_inches(target.x)),
Length::as_inches(Length::from_inches(target.y)),
);
let ((powl, powr), run_curr) = ctrl_algorithm.control(
Length::from_inches(tarx),
Length::from_inches(tary),
self.lookahead,
);
drivetrain.set_left_voltage(powl);
drivetrain.set_right_voltage(powr);
odom.tick().await;
run_curr
}
}