use std::time::Duration;
use glam::DVec2 as Vec2;
use ozton_control::{Tolerances, loops::Feedback};
use ozton_drivetrain::{Drivetrain, model::Arcade};
use ozton_tracking::{TracksForwardTravel, TracksHeading, TracksPosition, TracksVelocity};
use vexide::math::Angle;
mod drive;
mod turn_to_point;
pub use drive::DriveFuture;
pub use turn_to_point::TurnToPointFuture;
#[derive(PartialEq)]
pub struct Basic<L, A>
where
L: Feedback<State = f64, Signal = f64> + Unpin + Clone,
A: Feedback<State = Angle, Signal = f64> + Unpin + Clone,
{
pub linear_controller: L,
pub angular_controller: A,
pub linear_tolerances: Tolerances,
pub angular_tolerances: Tolerances,
pub timeout: Option<Duration>,
}
impl<L, A> Basic<L, A>
where
L: Feedback<State = f64, Signal = f64> + Unpin + Clone,
A: Feedback<State = Angle, Signal = f64> + Unpin + Clone,
{
pub fn drive_distance_at_heading<
'a,
M: Arcade,
T: TracksForwardTravel + TracksHeading + TracksVelocity,
>(
&mut self,
drivetrain: &'a mut Drivetrain<M, T>,
target_distance: f64,
target_heading: Angle,
) -> DriveFuture<'a, M, L, A, T> {
DriveFuture {
target_distance,
target_heading,
timeout: self.timeout,
linear_tolerances: self.linear_tolerances,
angular_tolerances: self.angular_tolerances,
linear_controller: self.linear_controller.clone(),
angular_controller: self.angular_controller.clone(),
drivetrain,
state: None,
}
}
pub fn drive_distance<
'a,
M: Arcade,
T: TracksForwardTravel + TracksHeading + TracksVelocity,
>(
&mut self,
drivetrain: &'a mut Drivetrain<M, T>,
distance: f64,
) -> DriveFuture<'a, M, L, A, T> {
self.drive_distance_at_heading(drivetrain, distance, drivetrain.tracking.heading())
}
pub fn turn_to_heading<
'a,
M: Arcade,
T: TracksForwardTravel + TracksHeading + TracksVelocity,
>(
&mut self,
drivetrain: &'a mut Drivetrain<M, T>,
heading: Angle,
) -> DriveFuture<'a, M, L, A, T> {
self.drive_distance_at_heading(drivetrain, 0.0, heading)
}
pub fn turn_to_point<
'a,
M: Arcade,
T: TracksForwardTravel + TracksPosition + TracksHeading + TracksVelocity,
>(
&mut self,
drivetrain: &'a mut Drivetrain<M, T>,
point: impl Into<Vec2>,
) -> TurnToPointFuture<'a, M, L, A, T> {
TurnToPointFuture {
point: point.into(),
timeout: self.timeout,
linear_tolerances: self.linear_tolerances,
angular_tolerances: self.angular_tolerances,
linear_controller: self.linear_controller.clone(),
angular_controller: self.angular_controller.clone(),
drivetrain,
state: None,
}
}
}