use core::time::Duration;
use evian_control::{Tolerances, loops::ControlLoop};
use evian_drivetrain::{Drivetrain, differential::Differential};
use evian_math::{Angle, Vec2};
use evian_tracking::{TracksForwardTravel, TracksHeading, TracksPosition, TracksVelocity};
mod distance_at_heading;
mod turn_to_point;
pub use distance_at_heading::DriveDistanceAtHeadingFuture;
pub use turn_to_point::TurnToPointFuture;
#[derive(PartialEq)]
pub struct Basic<
L: ControlLoop<Input = f64, Output = f64> + Unpin + Clone,
A: ControlLoop<Input = Angle, Output = 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: ControlLoop<Input = f64, Output = f64> + Unpin + Clone,
A: ControlLoop<Input = Angle, Output = f64> + Unpin + Clone,
> Basic<L, A>
{
pub fn drive_distance_at_heading<
'a,
T: TracksForwardTravel + TracksHeading + TracksVelocity,
>(
&mut self,
drivetrain: &'a mut Drivetrain<Differential, T>,
target_distance: f64,
target_heading: Angle,
) -> DriveDistanceAtHeadingFuture<'a, L, A, T> {
DriveDistanceAtHeadingFuture {
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, T: TracksForwardTravel + TracksHeading + TracksVelocity>(
&mut self,
drivetrain: &'a mut Drivetrain<Differential, T>,
distance: f64,
) -> DriveDistanceAtHeadingFuture<'a, L, A, T> {
self.drive_distance_at_heading(drivetrain, distance, drivetrain.tracking.heading())
}
pub fn turn_to_heading<'a, T: TracksForwardTravel + TracksHeading + TracksVelocity>(
&mut self,
drivetrain: &'a mut Drivetrain<Differential, T>,
heading: Angle,
) -> DriveDistanceAtHeadingFuture<'a, L, A, T> {
self.drive_distance_at_heading(drivetrain, 0.0, heading)
}
pub fn turn_to_point<
'a,
T: TracksForwardTravel + TracksPosition + TracksHeading + TracksVelocity,
>(
&mut self,
drivetrain: &'a mut Drivetrain<Differential, T>,
point: impl Into<Vec2<f64>>,
) -> TurnToPointFuture<'a, 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,
}
}
}