1
2
3
4
5
6 import socket, sys, time
7 from threading import Thread, Lock
8 from Tools import *
9 from SensorThread import SensorThread
10 from RobotInstance import RobotInstance
11 from ch.aplu.raspi import *
12 import thread
13
14
17
23
59
60
61
62 receiverTimeout = 10
63
64
73
74
77 Thread.__init__(self)
78 self.robot = robot
79
81 Tools.debug("Receiver thread started")
82 while self.robot.isReceiverRunning:
83 try:
84 self.robot.isReceiverUp = True
85 self.robot.receiverResponse = self.readResponse()
86 except:
87 Tools.debug("Exception in Receiver.run()")
88 self.robot.isReceiverRunning = False
89 self.robot.closeConnection()
90 Tools.debug("Receiver thread terminated")
91
93 Tools.debug("Calling readResponse")
94 bufSize = 4096
95 data = ""
96 while (not self.robot.isBinaryReply and not "\n" == data[-1:]) or \
97 (self.robot.isBinaryReply and not "\xff\xd9\n" in data[-3:]):
98
99
100
101 try:
102 reply = self.robot.sock.recv(bufSize)
103 except:
104 raise Exception("Exception from blocking sock.recv()")
105 data += reply
106 if not self.robot.isBinaryReply:
107 data = data.decode("UTF-8")
108 data = data[:-1]
109 self.robot.isBinaryReply = False
110 return data
111
112
114 '''
115 Class that creates or returns a single MyRobot instance.
116 '''
117 - def __new__(cls, ipAddress = "", buttonEvent = None):
126
127
129 _myInstance = None
130 - def __init__(self, ipAddress = "", buttonEvent = None):
131 if MyRobot._myInstance != None:
132 raise Exception("Only one instance of MyRobot allowed")
133
134 self.panel = ConnectPanel.create()
135 if ipAddress == "":
136 ipAddress_port = self.panel.askIPAddress()
137 if ipAddress_port == "":
138 raise RaspiException("No IP address given.")
139 else:
140 ipAddress_port = ipAddress
141 ipList = ipAddress_port.split(":")
142 self.ipAddress = ipList[0]
143 if len(ipList) == 2:
144 self.port = int(ipList[1])
145 else:
146 self.port = SharedConstants.PORT
147 self.isBinaryReply = False
148 self.isReceiverUp = False
149 self.isReceiverRunning = False
150 self.isExited = False
151 self.buttonHit = False
152 self.escapeHit = False
153 self.enterHit = False
154 self.upHit = False
155 self.downHit = False
156 self.leftHit = False
157 self.rightHit = False
158 self.sensorThread = None
159 self._buttonEvent = buttonEvent
160 self.isConn = False
161 self.lock = Lock()
162 self.panel.show()
163 self.panel.addCloseListener(onClose)
164 self.panel.addButtonKeyListener(KeyListener())
165 msg = "Connecting to " + self.ipAddress + ":" + str(self.port) + "..."
166 print msg,
167 self.panel.setText(msg)
168 if self.connect():
169 print "Connection established."
170 self.panel.showConnect(self.ipAddress + ":" + str(self.port))
171 Tools.delay(4000)
172 else:
173 self.panel.showFail(self.ipAddress, self.port)
174 raise RaspiException("Connection failed.")
175 MyRobot._myInstance = self
176 Tools.delay(2000)
177
179 if self.sensorThread == None:
180 self.sensorThread = SensorThread()
181 self.sensorThread.start()
182 self.sensorThread.add(sensor)
183
185 Tools.debug("Starting Receiver thread")
186 self.isReceiverRunning = True
187 receiver = Receiver(self)
188 receiver.start()
189 while not self.isReceiverUp:
190 time.sleep(0.001)
191 time.sleep(0.1)
192
194 self.lock.acquire()
195 Tools.debug("sendCommand() with cmd = " + cmd)
196 if not self.isConn:
197 raise RaspiException("Exception in Robot: sendCommand)() failed (Connection closed).")
198 return Response.SEND_FAILED
199 try:
200 self.receiverResponse = None
201 cmd += "\n";
202 self.sock.sendall(cmd)
203 reply = self.waitForReply()
204 self.lock.release()
205 return reply
206 except:
207 Tools.debug("Exception in sendCommand(): " + str(sys.exc_info()[1]))
208 self.closeConnection()
209
210 Tools.debug("Not connected. Returned: SEND_FAILED")
211 self.lock.release()
212 return Response.SEND_FAILED
213
215 Tools.debug("Calling waitForReply")
216 startTime = time.clock()
217 while self.isConn and self.receiverResponse == None and time.clock() - startTime < receiverTimeout:
218 time.sleep(0.01)
219 if self.receiverResponse == None:
220 raise RaspiException("Exception in Robot: waitForReply failed.")
221 Tools.debug("Response = " + self.receiverResponse)
222 return self.receiverResponse
223
225 if not self.isConn:
226 return
227 self.isConn = False
228 Tools.debug("Closing socket")
229 self.sock.shutdown(socket.SHUT_WR)
230 self.sock.close()
231
233 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
234 try:
235 self.sock.connect((self.ipAddress, self.port))
236 self.isConn = True
237 except Exception, err:
238
239 Tools.debug("Connection failed.")
240 return False
241 self.startReceiver()
242 return True
243
245 if self.isExited:
246 return
247 if self.sensorThread != None:
248 self.sensorThread.stop()
249 self.sensorThread.join(2000)
250 self.isExited = True
251 self.closeConnection()
252 self.escapeHit = True
253 self.buttonHit = True
254 msg = "Connection closed."
255 print msg
256 self.panel.setText(msg)
257 Tools.delay(5000)
258 self.panel.dispose()
259
263
266
269
272
274 return self.sendCommand("robot.setSoundVolume." + str(volume))
275
276 - def playTone(self, frequency, duration):
277 return self.sendCommand("robot.playTone." + str(int(frequency + 0.5)) + "." + str(int(duration + 0.5)))
278
280 return self.sendCommand("robot.initSound." + soundFile + "." + str(int(volume)))
281
284
287
289 return self.sendCommand("robot.fadeoutSound." + str(int(time)))
290
293
296
299
302
304 rc = self.sendCommand("robot.isSoundPlaying")
305 if rc == "1":
306 return True
307 return False
308
318
320 Tools.delay(1)
321 if self.escapeHit:
322 self.escapeHit = False
323 return True
324 return False
325
327 Tools.delay(1)
328 if self.enterHit:
329 self.enterHit = False
330 return True
331 return False
332
334 Tools.delay(1)
335 if self.upHit:
336 self.upHit = False
337 return True
338 return False
339
341 Tools.delay(1)
342 if self.downHit:
343 self.downHit = False
344 return True
345 return False
346
348 Tools.delay(1)
349 if self.leftHit:
350 self.leftHit = False
351 return True
352 return False
353
355 Tools.delay(1)
356 if self.rightHit:
357 self.rightHit = False
358 return True
359 return False
360
363