Skip to main content

ozton_motion/basic/
mod.rs

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