ev3_drivebase/drivebase/ramping.rs
1use std::ops::Div;
2
3use super::DriveBase;
4use ev3dev_lang_rust::Ev3Error;
5
6impl DriveBase {
7 /// Sets the acceleration rate for both motors.
8 ///
9 /// Acceleration determines how quickly the motors ramp up to the target speed.
10 /// Higher values result in faster acceleration but may cause wheel slipping or
11 /// mechanical stress. Lower values provide smoother, more controlled starts.
12 ///
13 /// # Parameters
14 ///
15 /// - `acceleration`: The acceleration rate in degrees per second squared (deg/s²)
16 ///
17 /// # Errors
18 ///
19 /// Returns an error if:
20 /// - The acceleration value is negative
21 /// - The value cannot be set on either motor
22 ///
23 /// # Examples
24 ///
25 /// ```no_run
26 /// use ev3_drivebase::{DriveBase, Motor, Direction};
27 /// use ev3_drivebase::ev3dev_lang_rust::{Ev3Error, motors::MotorPort};
28 ///
29 /// fn main() -> Result<(), Ev3Error> {
30 /// let left = Motor::new(MotorPort::OutA, Direction::Clockwise);
31 /// let right = Motor::new(MotorPort::OutB, Direction::CounterClockwise);
32 /// let drivebase = DriveBase::new(left, right, 43.2, 185.0)?;
33 ///
34 /// // Set moderate acceleration for smooth starts
35 /// drivebase.set_acceleration(2000)?;
36 ///
37 /// // Set high acceleration for quick response
38 /// drivebase.set_acceleration(5000)?;
39 ///
40 /// Ok(())
41 /// }
42 /// ```
43 pub fn set_acceleration(&self, acceleration: i32) -> Result<&Self, Ev3Error> {
44 let (left_time, right_time) = self.calculate_time(acceleration)?;
45 self.left.set_ramp_up_sp(left_time)?;
46 self.right.set_ramp_up_sp(right_time)?;
47 Ok(self)
48 }
49
50 /// Sets the deceleration rate for both motors.
51 ///
52 /// Deceleration determines how quickly the motors slow down when stopping.
53 /// Higher values result in faster stops but may cause the robot to jerk or tip.
54 /// Lower values provide smoother, more controlled stops.
55 ///
56 /// # Parameters
57 ///
58 /// - `deceleration`: The deceleration rate in degrees per second squared (deg/s²)
59 ///
60 /// # Errors
61 ///
62 /// Returns an error if:
63 /// - The deceleration value is negative
64 /// - The value cannot be set on either motor
65 ///
66 /// # Examples
67 ///
68 /// ```no_run
69 /// use ev3_drivebase::{DriveBase, Motor, Direction};
70 /// use ev3_drivebase::ev3dev_lang_rust::{Ev3Error, motors::MotorPort};
71 ///
72 /// fn main() -> Result<(), Ev3Error> {
73 /// let left = Motor::new(MotorPort::OutA, Direction::Clockwise);
74 /// let right = Motor::new(MotorPort::OutB, Direction::CounterClockwise);
75 /// let drivebase = DriveBase::new(left, right, 43.2, 185.0)?;
76 ///
77 /// // Set moderate deceleration for smooth stops
78 /// drivebase.set_deceleration(2000)?;
79 ///
80 /// // Set high deceleration for quick stops
81 /// drivebase.set_deceleration(5000)?;
82 ///
83 /// Ok(())
84 /// }
85 /// ```
86 ///
87 /// # Note
88 ///
89 /// Deceleration works in combination with the brake mode:
90 /// - With `BrakeMode::Coast`: Deceleration has limited effect
91 /// - With `BrakeMode::Brake` or `BrakeMode::Hold`: Full effect
92 pub fn set_deceleration(&self, deceleration: i32) -> Result<&Self, Ev3Error> {
93 let (left_time, right_time) = self.calculate_time(deceleration)?;
94 self.left.set_ramp_down_sp(left_time)?;
95 self.right.set_ramp_down_sp(right_time)?;
96 Ok(self)
97 }
98
99 fn calculate_time(&self, acceleration: i32) -> Result<(i32, i32), Ev3Error> {
100 let left_max_speed = self.left.get_max_speed()?;
101 let right_max_speed = self.right.get_max_speed()?;
102 let left_time = left_max_speed.div(acceleration);
103 let right_time = right_max_speed.div(acceleration);
104 Ok((left_time, right_time))
105 }
106}