evian_motion/basic/
mod.rs

1//! Feedback-driven driving and turning.
2
3use core::time::Duration;
4
5use evian_control::{Tolerances, loops::ControlLoop};
6use evian_drivetrain::{Drivetrain, differential::Differential};
7use evian_math::{Angle, Vec2};
8use evian_tracking::{TracksForwardTravel, TracksHeading, TracksPosition, TracksVelocity};
9
10mod distance_at_heading;
11mod turn_to_point;
12
13pub use distance_at_heading::DriveDistanceAtHeadingFuture;
14pub use turn_to_point::TurnToPointFuture;
15
16/// Feedback-driven driving and turning.
17#[derive(PartialEq)]
18pub struct Basic<
19    L: ControlLoop<Input = f64, Output = f64> + Unpin + Clone,
20    A: ControlLoop<Input = Angle, Output = f64> + Unpin + Clone,
21> {
22    /// Linear (forward driving) feedback controller.
23    pub linear_controller: L,
24
25    /// Angular (turning) feedback controller.
26    pub angular_controller: A,
27
28    /// Linear settling conditions.
29    pub linear_tolerances: Tolerances,
30
31    /// Angular settling conditions.
32    pub angular_tolerances: Tolerances,
33
34    /// Maximum duration the motion can take before being cancelled.
35    pub timeout: Option<Duration>,
36}
37
38impl<
39    L: ControlLoop<Input = f64, Output = f64> + Unpin + Clone,
40    A: ControlLoop<Input = Angle, Output = f64> + Unpin + Clone,
41> Basic<L, A>
42{
43    /// Moves the robot forwards by a given distance (measured in wheel units) while
44    /// turning to face a heading.
45    ///
46    /// Negative `target_distance` values will move the robot backwards.
47    pub fn drive_distance_at_heading<
48        'a,
49        T: TracksForwardTravel + TracksHeading + TracksVelocity,
50    >(
51        &mut self,
52        drivetrain: &'a mut Drivetrain<Differential, T>,
53        target_distance: f64,
54        target_heading: Angle,
55    ) -> DriveDistanceAtHeadingFuture<'a, L, A, T> {
56        DriveDistanceAtHeadingFuture {
57            target_distance,
58            target_heading,
59            timeout: self.timeout,
60            linear_tolerances: self.linear_tolerances,
61            angular_tolerances: self.angular_tolerances,
62            linear_controller: self.linear_controller.clone(),
63            angular_controller: self.angular_controller.clone(),
64            drivetrain,
65            state: None,
66        }
67    }
68
69    /// Moves the robot forwards by a given distance (measured in wheel units).
70    ///
71    /// Negative `distance` values will move the robot backwards.
72    pub fn drive_distance<'a, T: TracksForwardTravel + TracksHeading + TracksVelocity>(
73        &mut self,
74        drivetrain: &'a mut Drivetrain<Differential, T>,
75        distance: f64,
76    ) -> DriveDistanceAtHeadingFuture<'a, L, A, T> {
77        self.drive_distance_at_heading(drivetrain, distance, drivetrain.tracking.heading())
78    }
79
80    /// Turns the robot in place to face a heading.
81    pub fn turn_to_heading<'a, T: TracksForwardTravel + TracksHeading + TracksVelocity>(
82        &mut self,
83        drivetrain: &'a mut Drivetrain<Differential, T>,
84        heading: Angle,
85    ) -> DriveDistanceAtHeadingFuture<'a, L, A, T> {
86        self.drive_distance_at_heading(drivetrain, 0.0, heading)
87    }
88
89    /// Turns the robot in place to face a 2D point.
90    pub fn turn_to_point<
91        'a,
92        T: TracksForwardTravel + TracksPosition + TracksHeading + TracksVelocity,
93    >(
94        &mut self,
95        drivetrain: &'a mut Drivetrain<Differential, T>,
96        point: impl Into<Vec2<f64>>,
97    ) -> TurnToPointFuture<'a, L, A, T> {
98        TurnToPointFuture {
99            point: point.into(),
100            timeout: self.timeout,
101            linear_tolerances: self.linear_tolerances,
102            angular_tolerances: self.angular_tolerances,
103            linear_controller: self.linear_controller.clone(),
104            angular_controller: self.angular_controller.clone(),
105            drivetrain,
106            state: None,
107        }
108    }
109}