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