mod algorithm;
pub mod geo;
pub mod control;
const LOOPRATE: Duration = Duration::from_millis(10);
use std::time::Duration;
use control::PursuitControl;
use measurements::Length;
use vexide::time::sleep;
use crate::{
motion::{
odom::{devices::Pose, tracker::OdomTracker},
pursuit::algorithm::abs_arc_point,
},
peripherals::drivetrain::Differential,
};
#[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: &OdomTracker,
drivetrain: &Differential,
ctrl_algorithm: &C,
path: geo::Path,
) {
let mut run = true;
while run {
let odometry_values = odom.global_pose.lock().await;
let (x, y, t) = (
Length::from_inches(odometry_values.x),
Length::from_inches(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(Length::as_inches(&x), Length::as_inches(&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;
sleep(LOOPRATE).await;
}
}
pub async fn tick<C: PursuitControl>(
&self,
odom: &OdomTracker,
drivetrain: &Differential,
ctrl_algorithm: &C,
path: geo::Path,
) -> bool {
let odometry_values = odom.global_pose.lock().await;
let (x, y, t) = (
Length::from_inches(odometry_values.x),
Length::from_inches(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(Length::as_inches(&x), Length::as_inches(&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_curr
}
}