1extern crate serialport;
5
6use serialport::SerialPortSettings;
7use serialport::posix::*;
8use serialport::Error as sError;
9
10use std::{thread, time};
11use std::io::{Write, Read};
12use std::str;
13use std::path::Path;
14
15pub struct Arlo {
16 #[allow(dead_code)]
17 connection: TTYPort,
18 pub speed: Option<u8>,
19 pub turn_speed: Option<u8>,
20 pub step_time: Option<usize>,
21 pub turn_time: Option<usize>,
22}
23
24impl Arlo {
25 pub fn new() -> Result<Self, sError> {
26 let mut settings = SerialPortSettings::default();
27 settings.timeout = time::Duration::from_secs(60);
28 let conn = TTYPort::open(Path::new("/dev/ttyACM0"), &settings)?;
29 let wait = time::Duration::from_secs(2);
30 thread::sleep(wait);
31 Ok(Arlo {
32 connection: conn,
33 speed: None,
34 turn_speed: None,
35 step_time: None,
36 turn_time: None,
37 })
38 }
39
40 pub fn new_port(port: &str) -> Result<Self, sError> {
41 let mut settings = SerialPortSettings::default();
42 settings.timeout = time::Duration::from_secs(60);
43 let conn = TTYPort::open(Path::new(port), &settings)?;
44 let wait = time::Duration::from_secs(2);
45 thread::sleep(wait);
46 Ok(Arlo {
47 connection: conn,
48 speed: None,
49 turn_speed: None,
50 step_time: None,
51 turn_time: None,
52 })
53 }
54
55 fn send_command(&mut self, cmd: &str, sleep: Option<u64>) -> String {
57 use std::io::BufReader;
58 use std::io::BufRead;
59 let wait = match sleep {
60 Some(n) => n,
61 None => 0,
62 };
63 let conn: &mut TTYPort = &mut self.connection;
64 conn.write(cmd.as_bytes()).expect("Write failed");
65 thread::sleep(time::Duration::from_millis(wait));
66 let mut reader = BufReader::new(conn);
67 let mut line = String::new();
68 let _len = reader.read_line(&mut line).expect("Read failed");
69 line.trim().to_string()
71 }
72
73 pub fn go_diff(&mut self, power_left: u8, power_right: u8, dir_left: u8, dir_right: u8) -> String {
78 if power_left > 127 || power_right > 127 || dir_left > 1 || dir_right > 1 {
79 panic!("Reason: Variables set too high");
80 }
81 let cmd = format!("d{},{},{},{}\n", power_left, power_right, dir_left, dir_right);
82 self.send_command(&cmd, None)
83 }
84
85 pub fn stop(&mut self) -> String {
89 self.send_command("s\n", None)
90 }
91
92 pub fn go(&mut self) -> String {
94 if self.speed.is_none() {
95 panic!("Speed not set!");
96 }
97 let cmd = "g\n";
98 self.send_command(&cmd, None)
99 }
100
101 pub fn backward(&mut self) -> String {
103 if self.speed.is_none() {
104 panic!("Speed not set!");
105 }
106 let cmd = "v\n";
107 self.send_command(&cmd, None)
108 }
109
110 pub fn left(&mut self) -> String {
112 if self.speed.is_none() {
113 panic!("Speed not set!");
114 }
115 let cmd = "n\n";
116 self.send_command(&cmd, None)
117 }
118
119 pub fn right(&mut self) -> String {
121 if self.speed.is_none() {
122 panic!("Speed not set!");
123 }
124 let cmd = "m\n";
125 self.send_command(&cmd, None)
126 }
127
128 pub fn step_forward(&mut self) -> String {
131 if self.step_time.is_none() {
132 panic!("step_time not set!")
133 }
134 let cmd = "f\n";
135 self.send_command(&cmd, None)
136 }
137
138 pub fn step_backward(&mut self) -> String {
141 if self.step_time.is_none() {
142 panic!("step_time not set!")
143 }
144 let cmd = "b\n";
145 self.send_command(&cmd, None)
146 }
147
148 pub fn step_rotate_left(&mut self) -> String {
151 if self.turn_time.is_none() {
152 panic!("turn_time not set!")
153 }
154 let cmd = "l\n";
155 self.send_command(&cmd, None)
156 }
157
158 pub fn step_rotate_right(&mut self) -> String {
161 if self.turn_time.is_none() {
162 panic!("turn_time not set!")
163 }
164 let cmd = "r\n";
165 self.send_command(&cmd, None)
166 }
167
168 fn read_sensor(&mut self, sensor_id: u8) -> Result<usize, ()> {
170 let cmd = format!("{}\n", sensor_id);
171 let return_value = self.send_command(&cmd, None).parse::<usize>().map_err(|_| ())?;
172 if return_value <= 0 {
174 Err(())
175 } else {
176 Ok(return_value)
177 }
178 }
179 pub fn read_front_ping_sensor(&mut self) -> Result<usize, ()> {
181 self.read_sensor(0)
182 }
183
184 pub fn read_back_ping_sensor(&mut self) -> Result<usize, ()> {
186 self.read_sensor(1)
187 }
188 pub fn read_left_ping_sensor(&mut self) -> Result<usize, ()> {
190 self.read_sensor(2)
191 }
192
193 pub fn read_right_ping_sensor(&mut self) -> Result<usize, ()> {
195 self.read_sensor(3)
196 }
197
198 pub fn set_speed(&mut self, speed: u8) -> String {
201 self.speed = Some(speed);
202 let cmd = format!("z{}\n", speed);
203 self.send_command(&cmd, None)
204 }
205
206 pub fn set_turnspeed(&mut self, turn_speed: u8) -> String {
209 self.turn_speed = Some(turn_speed);
210 let cmd = format!("x{}\n", turn_speed);
211 self.send_command(&cmd, None)
212 }
213
214 pub fn set_step_time(&mut self, step_time: usize) -> String {
217 self.step_time = Some(step_time);
218 let cmd = format!("t{}\n", step_time);
219 self.send_command(&cmd, None)
220 }
221
222 pub fn set_turn_time(&mut self, step_time: usize) -> String {
225 self.step_time = Some(step_time);
226 let cmd = format!("y{}\n", step_time);
227 self.send_command(&cmd, None)
228 }
229
230 pub fn read_left_wheel_encoder(&mut self) -> usize {
233 let cmd = "e0\n";
234 self.send_command(&cmd, Some(45)).parse::<usize>().unwrap()
235 }
236
237 pub fn read_right_wheel_encoder(&mut self) -> usize {
240 let cmd = "e1\n";
241 self.send_command(&cmd, Some(45)).parse::<usize>().unwrap()
242 }
243
244 pub fn reset_encoder_counts(&mut self) -> String {
246 self.send_command("c\n", None)
247 }
248}
249
250impl Drop for Arlo {
251 fn drop(&mut self) {
252 println!("Shutting down the robot ...");
253 let wait = time::Duration::from_millis(5);
254 let long_wait = time::Duration::from_millis(10);
255 thread::sleep(wait);
256 self.stop();
257 thread::sleep(long_wait);
258 self.send_command("k\n", None);
259 }
260}