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 std::cell::Cell;
use super::SensorPort;
use crate::{Attribute, Device, Driver, Ev3Error, Ev3Result};
#[derive(Debug, Clone, Device)]
pub struct UltrasonicSensor {
driver: Driver,
cm_scale: Cell<Option<f32>>,
in_scale: Cell<Option<f32>>,
}
impl UltrasonicSensor {
fn new(driver: Driver) -> Self {
Self {
driver,
cm_scale: Cell::new(None),
in_scale: Cell::new(None),
}
}
findable!(
"lego-sensor",
"lego-ev3-us",
SensorPort,
"UltrasonicSensor",
"in"
);
pub const MODE_US_DIST_CM: &'static str = "US-DIST-CM";
pub const MODE_US_DIST_IN: &'static str = "US-DIST-IN";
pub const MODE_US_LISTEN: &'static str = "US-LISTEN";
pub const MODE_US_SI_CM: &'static str = "US-SI-CM";
pub const MODE_US_SI_IN: &'static str = "US-SI-IN";
pub const MODE_US_DC_CM: &'static str = "US-DC-CM";
pub const MODE_US_DC_IN: &'static str = "US-DC-IN";
sensor!();
pub fn set_mode_us_dist_cm(&self) -> Ev3Result<()> {
self.set_mode(Self::MODE_US_DIST_CM)
}
pub fn set_mode_us_dist_in(&self) -> Ev3Result<()> {
self.set_mode(Self::MODE_US_DIST_IN)
}
pub fn set_mode_us_listen(&self) -> Ev3Result<()> {
self.set_mode(Self::MODE_US_LISTEN)
}
pub fn set_mode_us_si_cm(&self) -> Ev3Result<()> {
self.set_mode(Self::MODE_US_SI_CM)
}
pub fn set_mode_us_si_in(&self) -> Ev3Result<()> {
self.set_mode(Self::MODE_US_SI_IN)
}
pub fn set_mode_us_dc_cm(&self) -> Ev3Result<()> {
self.set_mode(Self::MODE_US_DC_CM)
}
pub fn set_mode_us_dc_in(&self) -> Ev3Result<()> {
self.set_mode(Self::MODE_US_DC_IN)
}
pub fn get_distance(&self) -> Ev3Result<i32> {
self.get_value0()
}
pub fn get_distance_centimeters(&self) -> Ev3Result<f32> {
let scale_field = self.cm_scale.get();
let scale = match scale_field {
Some(s) => s,
None => {
let decimals = self.get_decimals()?;
let s = 10f32.powi(-decimals);
self.cm_scale.set(Some(s));
s
}
};
Ok((self.get_value0()? as f32) * scale)
}
pub fn get_distance_inches(&self) -> Ev3Result<f32> {
let scale_field = self.in_scale.get();
let scale = match scale_field {
Some(s) => s,
None => {
let decimals = self.get_decimals()?;
let s = 10f32.powi(-decimals);
self.in_scale.set(Some(s));
s
}
};
Ok((self.get_value0()? as f32) * scale)
}
}