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 neato_driver.py is a generic driver for the Neato XV-11 Robotic Vacuum.
30 ROS Bindings can be found in the neato_node package.
31 """
32
33 __author__ = "ferguson@cs.albany.edu (Michael Ferguson)"
34
35 import serial
36
37 BASE_WIDTH = 248
38 MAX_SPEED = 300
39
40 xv11_analog_sensors = [ "WallSensorInMM",
41 "BatteryVoltageInmV",
42 "LeftDropInMM",
43 "RightDropInMM",
44 "RightMagSensor",
45 "LeftMagSensor",
46 "XTemp0InC",
47 "XTemp1InC",
48 "VacuumCurrentInmA",
49 "ChargeVoltInmV",
50 "NotConnected1",
51 "BatteryTemp1InC",
52 "NotConnected2",
53 "CurrentInmA",
54 "NotConnected3",
55 "BatteryTemp0InC" ]
56
57 xv11_digital_sensors = [ "SNSR_DC_JACK_CONNECT",
58 "SNSR_DUSTBIN_IS_IN",
59 "SNSR_LEFT_WHEEL_EXTENDED",
60 "SNSR_RIGHT_WHEEL_EXTENDED",
61 "LSIDEBIT",
62 "LFRONTBIT",
63 "RSIDEBIT",
64 "RFRONTBIT" ]
65
66 xv11_motor_info = [ "Brush_MaxPWM",
67 "Brush_PWM",
68 "Brush_mVolts",
69 "Brush_Encoder",
70 "Brush_RPM",
71 "Vacuum_MaxPWM",
72 "Vacuum_PWM",
73 "Vacuum_CurrentInMA",
74 "Vacuum_Encoder",
75 "Vacuum_RPM",
76 "LeftWheel_MaxPWM",
77 "LeftWheel_PWM",
78 "LeftWheel_mVolts",
79 "LeftWheel_Encoder",
80 "LeftWheel_PositionInMM",
81 "LeftWheel_RPM",
82 "RightWheel_MaxPWM",
83 "RightWheel_PWM",
84 "RightWheel_mVolts",
85 "RightWheel_Encoder",
86 "RightWheel_PositionInMM",
87 "RightWheel_RPM",
88 "Laser_MaxPWM",
89 "Laser_PWM",
90 "Laser_mVolts",
91 "Laser_Encoder",
92 "Laser_RPM",
93 "Charger_MaxPWM",
94 "Charger_PWM",
95 "Charger_mAH" ]
96
97 xv11_charger_info = [ "FuelPercent",
98 "BatteryOverTemp",
99 "ChargingActive",
100 "ChargingEnabled",
101 "ConfidentOnFuel",
102 "OnReservedFuel",
103 "EmptyFuel",
104 "BatteryFailure",
105 "ExtPwrPresent",
106 "ThermistorPresent[0]",
107 "ThermistorPresent[1]",
108 "BattTempCAvg[0]",
109 "BattTempCAvg[1]",
110 "VBattV",
111 "VExtV",
112 "Charger_mAH",
113 "MaxPWM" ]
114
116
117 - def __init__(self, port="/dev/ttyUSB0"):
118 self.port = serial.Serial(port,115200)
119
120 self.state = {"LeftWheel_PositionInMM": 0, "RightWheel_PositionInMM": 0}
121 self.stop_state = True
122
123 self.setTestMode("on")
124 self.setLDS("on")
125
129
131 """ Turn test mode on/off. """
132 self.port.write("testmode " + value + "\n")
133
135 self.port.write("setldsrotation " + value + "\n")
136
138 """ Ask neato for an array of scan reads. """
139 self.port.flushInput()
140 self.port.write("getldsscan\n")
141
143 """ Read values of a scan -- call requestScan first! """
144 ranges = list()
145 angle = 0
146 try:
147 line = self.port.readline()
148 except:
149 return []
150 while line.split(",")[0] != "AngleInDegrees":
151 try:
152 line = self.port.readline()
153 except:
154 return []
155 while angle < 360:
156 try:
157 vals = self.port.readline()
158 except:
159 pass
160 vals = vals.split(",")
161
162 try:
163 a = int(vals[0])
164 r = int(vals[1])
165 ranges.append(r/1000.0)
166 except:
167 ranges.append(0)
168 angle += 1
169 return ranges
170
172 """ Set motors, distance left & right + speed """
173
174
175
176
177
178 if (int(l) == 0 and int(r) == 0 and int(s) == 0):
179 if (not self.stop_state):
180 self.stop_state = True
181 l = 1
182 r = 1
183 s = 1
184 else:
185 self.stop_state = False
186
187 self.port.write("setmotor "+str(int(l))+" "+str(int(r))+" "+str(int(s))+"\n")
188
190 """ Update values for motors in the self.state dictionary.
191 Returns current left, right encoder values. """
192 self.port.flushInput()
193 self.port.write("getmotors\n")
194 line = self.port.readline()
195 while line.split(",")[0] != "Parameter":
196 try:
197 line = self.port.readline()
198 except:
199 return [0,0]
200 for i in range(len(xv11_motor_info)):
201 try:
202 values = self.port.readline().split(",")
203 self.state[values[0]] = int(values[1])
204 except:
205 pass
206 return [self.state["LeftWheel_PositionInMM"],self.state["RightWheel_PositionInMM"]]
207
209 """ Update values for analog sensors in the self.state dictionary. """
210 self.port.write("getanalogsensors\n")
211 line = self.port.readline()
212 while line.split(",")[0] != "SensorName":
213 try:
214 line = self.port.readline()
215 except:
216 return
217 for i in range(len(xv11_analog_sensors)):
218 try:
219 values = self.port.readline().split(",")
220 self.state[values[0]] = int(values[1])
221 except:
222 pass
223
225 """ Update values for digital sensors in the self.state dictionary. """
226 self.port.write("getdigitalsensors\n")
227 line = self.port.readline()
228 while line.split(",")[0] != "Digital Sensor Name":
229 try:
230 line = self.port.readline()
231 except:
232 return
233 for i in range(len(xv11_digital_sensors)):
234 try:
235 values = self.port.readline().split(",")
236 self.state[values[0]] = int(values[1])
237 except:
238 pass
239
241 """ Update values for charger/battery related info in self.state dictionary. """
242 self.port.write("getcharger\n")
243 line = self.port.readline()
244 while line.split(",")[0] != "Label":
245 line = self.port.readline()
246 for i in range(len(xv11_charger_info)):
247 values = self.port.readline().split(",")
248 try:
249 self.state[values[0]] = int(values[1])
250 except:
251 pass
252
254 if value > 0:
255 self.port.write("setled backlighton")
256 else:
257 self.port.write("setled backlightoff")
258
259
260
261
262
263
264
265
266
267
268
269