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}