ev3dev_lang_rust/motors/
dc_motor_macro.rs

1//! The DcMotor provides a uniform interface for using
2//! regular DC motors with no fancy controls or feedback.
3//! This includes LEGO MINDSTORMS RCX motors and LEGO Power Functions motors.
4
5/// The DcMotor provides a uniform interface for using
6/// regular DC motors with no fancy controls or feedback.
7/// This includes LEGO MINDSTORMS RCX motors and LEGO Power Functions motors.
8#[macro_export]
9macro_rules! dc_motor {
10    () => {
11        /// Causes the motor to run until another command is sent.
12        pub const COMMAND_RUN_FOREVER: &'static str = "run-forever";
13
14        /// Run the motor for the amount of time specified in `time_sp`
15        /// and then stops the motor using the command specified by `stop_action`.
16        pub const COMMAND_RUN_TIMED: &'static str = "run-timed";
17
18        /// Runs the motor using the duty cycle specified by `duty_cycle_sp`.
19        /// Unlike other run commands, changing `duty_cycle_sp` while running will take effect immediately.
20        pub const COMMAND_RUN_DIRECT: &'static str = "run-direct";
21
22        /// Stop any of the run commands before they are complete using the command specified by `stop_action`.
23        pub const COMMAND_STOP: &'static str = "stop";
24
25        /// A positive duty cycle will cause the motor to rotate clockwise.
26        pub const POLARITY_NORMAL: &'static str = "normal";
27
28        /// A positive duty cycle will cause the motor to rotate counter-clockwise.
29        pub const POLARITY_INVERSED: &'static str = "inversed";
30
31        /// Power is being sent to the motor.
32        pub const STATE_RUNNING: &'static str = "running";
33
34        /// The motor is ramping up or down and has not yet reached a pub constant output level.
35        pub const STATE_RAMPING: &'static str = "ramping";
36
37        /// Removes power from the motor. The motor will freely coast to a stop.
38        pub const STOP_ACTION_COAST: &'static str = "coast";
39
40        /// Removes power from the motor and creates a passive electrical load.
41        /// This is usually done by shorting the motor terminals together.
42        /// This load will absorb the energy from the rotation of the motors
43        /// and cause the motor to stop more quickly than coasting.
44        pub const STOP_ACTION_BRAKE: &'static str = "brake";
45
46        /// Returns the current duty cycle of the motor. Units are percent. Values are -100 to 100.
47        pub fn get_duty_cycle(&self) -> Ev3Result<i32> {
48            self.get_attribute("duty_cycle").get()
49        }
50
51        /// Returns the current duty cycle setpoint of the motor. Units are in percent.
52        /// Valid values are -100 to 100. A negative value causes the motor to rotate in reverse.
53        pub fn get_duty_cycle_sp(&self) -> Ev3Result<i32> {
54            self.get_attribute("duty_cycle_sp").get()
55        }
56
57        /// Sets the duty cycle setpoint of the motor. Units are in percent.
58        /// Valid values are -100 to 100. A negative value causes the motor to rotate in reverse.
59        pub fn set_duty_cycle_sp(&self, duty_cycle_sp: i32) -> Ev3Result<()> {
60            self.get_attribute("duty_cycle_sp").set(duty_cycle_sp)
61        }
62
63        /// Returns the current polarity of the motor.
64        pub fn get_polarity(&self) -> Ev3Result<String> {
65            self.get_attribute("polarity").get()
66        }
67
68        /// Sets the polarity of the motor.
69        pub fn set_polarity(&self, polarity: &str) -> Ev3Result<()> {
70            self.get_attribute("polarity").set_str_slice(polarity)
71        }
72
73        /// Returns the current ramp up setpoint.
74        /// Units are in milliseconds and must be positive. When set to a non-zero value,
75        /// the motor speed will increase from 0 to 100% of `max_speed` over the span of this setpoint.
76        /// The actual ramp time is the ratio of the difference between the speed_sp
77        /// and the current speed and max_speed multiplied by ramp_up_sp. Values must not be negative.
78        pub fn get_ramp_up_sp(&self) -> Ev3Result<i32> {
79            self.get_attribute("ramp_up_sp").get()
80        }
81
82        /// Sets the ramp up setpoint.
83        /// Units are in milliseconds and must be positive. When set to a non-zero value,
84        /// the motor speed will increase from 0 to 100% of `max_speed` over the span of this setpoint.
85        /// The actual ramp time is the ratio of the difference between the speed_sp
86        /// and the current speed and max_speed multiplied by ramp_up_sp. Values must not be negative.
87        pub fn set_ramp_up_sp(&self, ramp_up_sp: i32) -> Ev3Result<()> {
88            self.get_attribute("ramp_up_sp").set(ramp_up_sp)
89        }
90
91        /// Returns the current ramp down setpoint.
92        /// Units are in milliseconds and must be positive. When set to a non-zero value,
93        /// the motor speed will decrease from 100% down to 0 of `max_speed` over the span of this setpoint.
94        /// The actual ramp time is the ratio of the difference between the speed_sp
95        /// and the current speed and 0 multiplied by ramp_down_sp. Values must not be negative.
96        pub fn get_ramp_down_sp(&self) -> Ev3Result<i32> {
97            self.get_attribute("ramp_down_sp").get()
98        }
99
100        /// Sets the ramp down setpoint.
101        /// Units are in milliseconds and must be positive. When set to a non-zero value,
102        /// the motor speed will decrease from 100% down to 0 of `max_speed` over the span of this setpoint.
103        /// The actual ramp time is the ratio of the difference between the speed_sp
104        /// and the current speed and 0 multiplied by ramp_down_sp. Values must not be negative.
105        pub fn set_ramp_down_sp(&self, ramp_down_sp: i32) -> Ev3Result<()> {
106            self.get_attribute("ramp_down_sp").set(ramp_down_sp)
107        }
108
109        /// Returns a list of state flags.
110        pub fn get_state(&self) -> Ev3Result<Vec<String>> {
111            self.get_attribute("state").get_vec()
112        }
113
114        /// Returns the current stop action.
115        /// The value determines the motors behavior when command is set to stop.
116        pub fn get_stop_action(&self) -> Ev3Result<String> {
117            self.get_attribute("stop_action").get()
118        }
119
120        /// Sets the stop action.
121        /// The value determines the motors behavior when command is set to stop.
122        pub fn set_stop_action(&self, stop_action: &str) -> Ev3Result<()> {
123            self.get_attribute("stop_action").set_str_slice(stop_action)
124        }
125
126        /// Returns the current amount of time the motor will run when using the run-timed command.
127        /// Units are in milliseconds. Values must not be negative.
128        pub fn get_time_sp(&self) -> Ev3Result<i32> {
129            self.get_attribute("time_sp").get()
130        }
131
132        /// Sets the amount of time the motor will run when using the run-timed command.
133        /// Units are in milliseconds. Values must not be negative.
134        pub fn set_time_sp(&self, time_sp: i32) -> Ev3Result<()> {
135            self.get_attribute("time_sp").set(time_sp)
136        }
137
138        /// Runs the motor using the duty cycle specified by `duty_cycle_sp`.
139        /// Unlike other run commands, changing `duty_cycle_sp` while running will take effect immediately.
140        pub fn run_direct(&self) -> Ev3Result<()> {
141            self.set_command(Self::COMMAND_RUN_DIRECT)
142        }
143
144        /// Causes the motor to run until another command is sent.
145        pub fn run_forever(&self) -> Ev3Result<()> {
146            self.set_command(Self::COMMAND_RUN_FOREVER)
147        }
148
149        /// Run the motor for the amount of time specified in `time_sp`
150        /// and then stops the motor using the command specified by `stop_action`.
151        pub fn run_timed(&self, time_sp: Option<Duration>) -> Ev3Result<()> {
152            if let Some(duration) = time_sp {
153                let p = duration.as_millis() as i32;
154                self.set_time_sp(p)?;
155            }
156            self.set_command(Self::COMMAND_RUN_TIMED)
157        }
158
159        /// Stop any of the run commands before they are complete using the command specified by `stop_action`.
160        pub fn stop(&self) -> Ev3Result<()> {
161            self.set_command(Self::COMMAND_STOP)
162        }
163
164        /// Power is being sent to the motor.
165        pub fn is_running(&self) -> Ev3Result<bool> {
166            Ok(self
167                .get_state()?
168                .iter()
169                .any(|state| state == Self::STATE_RUNNING))
170        }
171
172        /// The motor is ramping up or down and has not yet reached a pub constant output level.
173        pub fn is_ramping(&self) -> Ev3Result<bool> {
174            Ok(self
175                .get_state()?
176                .iter()
177                .any(|state| state == Self::STATE_RAMPING))
178        }
179    };
180}