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
use crate::{Motor, MotorError};
use hal::I2cdev;
use lazy_static::lazy_static;
use linux_embedded_hal as hal;
use pwm_pca9685::{Channel, Pca9685};
use std::cmp::Ordering;
use std::collections::HashMap;
lazy_static! {
pub static ref DC_CHANNEL_MAP: HashMap<Motor, DcChannels> = {
let mut map = HashMap::new();
map.insert(
Motor::Motor1,
DcChannels {
ref_channel: Channel::C8,
forward_channel: Channel::C9,
backward_channel: Channel::C10,
},
);
map.insert(
Motor::Motor2,
DcChannels {
ref_channel: Channel::C13,
forward_channel: Channel::C11,
backward_channel: Channel::C12,
},
);
map.insert(
Motor::Motor3,
DcChannels {
ref_channel: Channel::C2,
forward_channel: Channel::C3,
backward_channel: Channel::C4,
},
);
map.insert(
Motor::Motor4,
DcChannels {
ref_channel: Channel::C7,
forward_channel: Channel::C5,
backward_channel: Channel::C6,
},
);
map
};
}
#[derive(Clone, Copy)]
pub struct DcChannels {
ref_channel: Channel,
forward_channel: Channel,
backward_channel: Channel,
}
pub struct DcMotor {
channels: DcChannels,
}
impl DcMotor {
pub fn try_new(
pwm: &mut Pca9685<I2cdev>,
motor: Motor,
) -> Result<Self, MotorError> {
let channels = DC_CHANNEL_MAP
.get(&motor)
.ok_or(MotorError::InvalidMotorError)?;
pwm.set_channel_on(channels.ref_channel, 0)
.map_err(|_| MotorError::ChannelError)?;
pwm.set_channel_on(channels.forward_channel, 0)
.map_err(|_| MotorError::ChannelError)?;
pwm.set_channel_on(channels.backward_channel, 0)
.map_err(|_| MotorError::ChannelError)?;
pwm.set_channel_off(channels.ref_channel, 4095)
.map_err(|_| MotorError::ChannelError)?;
Ok(Self {
channels: *channels,
})
}
pub fn set_throttle(
&mut self,
pwm: &mut Pca9685<I2cdev>,
throttle: f32,
) -> Result<(), MotorError> {
if throttle > 1.0 || throttle < -1.0 {
return Err(MotorError::ThrottleError);
}
let duty_cycle = (4095.0 * throttle.abs()) as u16;
match throttle.partial_cmp(&0.0) {
Some(Ordering::Greater) => {
pwm.set_channel_off(self.channels.forward_channel, duty_cycle)
.map_err(|_| MotorError::ChannelError)?;
}
Some(Ordering::Less) => {
pwm.set_channel_off(self.channels.backward_channel, duty_cycle)
.map_err(|_| MotorError::ChannelError)?;
}
_ => {
pwm.set_channel_full_off(self.channels.forward_channel)
.map_err(|_| MotorError::ChannelError)?;
pwm.set_channel_full_off(self.channels.backward_channel)
.map_err(|_| MotorError::ChannelError)?;
}
}
Ok(())
}
pub fn stop(
&mut self,
pwm: &mut Pca9685<I2cdev>,
) -> Result<(), MotorError> {
pwm.set_channel_full_off(self.channels.ref_channel)
.map_err(|_| MotorError::ChannelError)?;
pwm.set_channel_full_off(self.channels.forward_channel)
.map_err(|_| MotorError::ChannelError)?;
pwm.set_channel_full_off(self.channels.backward_channel)
.map_err(|_| MotorError::ChannelError)?;
Ok(())
}
}