ev3_drivebase/drivebase/drive.rs
1use super::DriveBase;
2use crate::Direction;
3use ev3dev_lang_rust::Ev3Error;
4
5impl DriveBase {
6 /// Drives the robot forward or backward for a specified distance.
7 ///
8 /// The robot will drive in a straight line at the given speed until it has traveled
9 /// the specified distance, then stop according to the configured brake mode.
10 ///
11 /// # Parameters
12 ///
13 /// - `speed`: The speed in degrees per second. Positive values use forward direction,
14 /// negative values reverse the direction.
15 /// - `distance`: The distance to travel in millimeters. Positive for forward, negative for backward.
16 /// - `stop`: Whether to stop the motors after reaching the target distance.
17 /// - `true`: Motors will stop when the distance is reached
18 /// - `false`: Motors will continue running at the same speed after reaching the distance
19 ///
20 /// # Errors
21 ///
22 /// Returns an error if:
23 /// - The motors cannot be commanded
24 /// - Speed or distance calculations fail
25 ///
26 /// # Examples
27 ///
28 /// Basic forward and backward movement:
29 ///
30 /// ```no_run
31 /// use ev3_drivebase::{DriveBase, Motor, Direction, BrakeMode};
32 /// use ev3_drivebase::ev3dev_lang_rust::{Ev3Error, motors::MotorPort};
33 ///
34 /// fn main() -> Result<(), Ev3Error> {
35 /// let left = Motor::new(MotorPort::OutA, Direction::Clockwise);
36 /// let right = Motor::new(MotorPort::OutB, Direction::CounterClockwise);
37 /// let mut drivebase = DriveBase::new(left, right, 43.2, 185.0)?;
38 /// drivebase.set_brake_mode(BrakeMode::Hold)?;
39 ///
40 /// // Drive forward 300mm at 200 deg/s and stop
41 /// drivebase.drive(200, 300, true)?;
42 ///
43 /// // Drive backward 150mm at 100 deg/s and stop
44 /// drivebase.drive(100, -150, true)?;
45 ///
46 /// // Drive forward 500mm and continue running
47 /// drivebase.drive(300, 500, false)?;
48 ///
49 /// Ok(())
50 /// }
51 /// ```
52 ///
53 /// # Behavior
54 ///
55 /// - If `distance` is 0, the method returns immediately without moving
56 /// - The direction of travel is determined by the sign of `distance`
57 /// - The method blocks until the robot reaches the target distance
58 /// - Motor speeds are automatically adjusted based on the configured motor directions
59 pub fn drive(
60 &mut self,
61 speed: i32,
62 distance: impl Into<i32>,
63 stop: bool,
64 ) -> Result<&Self, Ev3Error> {
65 let distance: i32 = distance.into();
66 if distance == 0 {
67 return Ok(self);
68 }
69
70 let direction = if distance < 0 {
71 Direction::CounterClockwise
72 } else {
73 Direction::Clockwise
74 };
75
76 self.set_speed(speed, speed)?;
77
78 let mut counts = self.calculate_counts(distance, distance)?;
79
80 counts.0 = counts.0.saturating_mul(direction.sign());
81 counts.1 = counts.1.saturating_mul(direction.sign());
82
83 self.run_to_rel_pos(counts.0, counts.1)?;
84 self.wait_until_not_moving(None);
85
86 if !stop {
87 self.run_forever()?;
88 }
89
90 Ok(self)
91 }
92}