source: trunk/brainstorms/Puzzlebox/Brainstorms/Interface.py @ 237

Last change on this file since 237 was 237, checked in by sc, 11 years ago

brainstorms/Puzzlebox/Brainstorms/Interface.py:

  • toggled/checked states of hover and fly_forward fixed
File size: 49.2 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Puzzlebox - Brainstorms - Client Interface - Qt
5#
6# Copyright Puzzlebox Productions, LLC (2010)
7#
8# This code is released under the GNU Pulic License (GPL) version 2
9# For more information please refer to http://www.gnu.org/copyleft/gpl.html
10
11__changelog__ = """\
12Last Update: 2010.11.30
13
14"""
15
16__todo__ = """
17 - server may not correctly handle multiple clients connected
18      to an embedded Brainstorms server
19 - disable autorepeating on shortcut keys
20 - update configuration.ini file with settings entered into interface
21
22"""
23
24import os, sys
25import urllib
26
27if (sys.platform == 'win32'):
28        import _winreg as winreg
29        import itertools
30        import re
31        import serial
32else:
33        import bluetooth
34
35try:
36        import PySide as PyQt4
37        from PySide import QtCore, QtGui, QtNetwork
38except:
39        print "Using PyQt4 module"
40        from PyQt4 import QtCore, QtGui, QtNetwork
41else:
42        print "Using PySide module"
43
44#from PyQt4 import QtCore, QtGui, QtNetwork
45#from PySide import QtCore, QtGui, QtNetwork
46
47from Interface_Design import Ui_Form as Design
48
49import simplejson as json
50
51import Configuration as configuration
52import Client as brainstorms_client
53import Puzzlebox.Brainstorms.ThinkGear.Client as thinkgear_client
54import Helicopter_Control as helicopter_control
55#import puzzlebox_logger
56
57#####################################################################
58# Globals
59#####################################################################
60
61DEBUG = 1
62
63THINKGEAR_POWER_THRESHOLDS = configuration.THINKGEAR_POWER_THRESHOLDS
64
65BLUETOOTH_DEVICE = configuration.NXT_BLUETOOTH_DEVICE
66
67NXT_BLUETOOTH_DEVICE = configuration.NXT_BLUETOOTH_DEVICE
68
69DEFAULT_NXT_POWER_LEVEL = configuration.DEFAULT_NXT_POWER_LEVEL
70
71THINKGEAR_SERVER_HOST = configuration.THINKGEAR_SERVER_HOST
72THINKGEAR_SERVER_PORT = configuration.THINKGEAR_SERVER_PORT
73
74BRAINSTORMS_FEEDBACK_URL = 'http://brainstorms.puzzlebox.info/contact_cgi.php'
75
76DEVICE_PATH = '/dev'
77PATH_TO_HCITOOL = '/usr/bin/hcitool'
78
79#####################################################################
80# Classes
81#####################################################################
82
83class puzzlebox_brainstorms_client_interface(QtGui.QWidget, Design):
84       
85        def __init__(self, log, server=None, DEBUG=DEBUG, parent = None):
86               
87                self.log = log
88                self.DEBUG = DEBUG
89               
90                QtGui.QWidget.__init__(self, parent)
91                self.setupUi(self)
92               
93                self.configureSettings()
94                self.connectWidgets()
95               
96                self.name = "Brainstorms Interface"
97               
98                self.brainstormsServer = server
99                self.brainstormsClient = None
100               
101                self.helicopter = None
102                self.wheelchair = None
103               
104                self.drive_state = 'stop_motors'
105                self.current_speed = 0
106       
107       
108        ##################################################################
109       
110        def configureSettings(self):
111               
112                # Brainstorms Interface
113               
114                icon = QtGui.QIcon()
115                icon.addPixmap(QtGui.QPixmap("images/puzzlebox.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
116                self.setWindowIcon(icon)
117               
118                self.pushButtonTurnLeft.setEnabled(False)
119                self.pushButtonForward.setEnabled(False)
120                self.pushButtonTurnRight.setEnabled(False)
121                self.pushButtonTurnLeftReverse.setEnabled(False)
122                self.pushButtonReverse.setEnabled(False)
123                self.pushButtonTurnRightReverse.setEnabled(False)
124               
125                self.pushButtonConcentrationEnable.setDown(True)
126                self.pushButtonRelaxationEnable.setDown(True)
127                self.pushButtonSpeedEnable.setDown(True)
128               
129               
130                # Search for available Serial and Bluetooth devices
131                self.searchForDevices()
132               
133               
134                # LEGO Mindstorms
135                self.textLabelNXTStatus.setText("Status: Disconnected")
136               
137                # Display communication port for LEGO Mindstorms NXT device
138                #self.lineEditNXTPort.setText(NXT_BLUETOOTH_DEVICE)
139                self.comboBoxNXTPortSelect.setEnabled(True)
140               
141               
142                # RC Helicopter
143                self.textLabelHelicopterStatus.setText("Status: Disconnected")
144               
145               
146                # Wheelchair
147                self.textLabelWheelchairStatus.setText("Status: Disconnected")
148               
149               
150                # Control Panel
151               
152                # Display Host for ThinkGear Connect Socket Server
153                self.lineEditThinkGearHost.setText(THINKGEAR_SERVER_HOST)
154                #self.lineEditThinkGearHost.setEnabled(False)
155               
156                # Display Port for ThinkGear Connect Socket Server
157                self.lineEditThinkGearPort.setText('%i' % THINKGEAR_SERVER_PORT)
158                #self.lineEditThinkGearPort.setEnabled(False)
159               
160               
161                self.lineEditLeftMotorPort.setText( \
162                   configuration.NXT_MOTOR_PORT_LEFT.upper() )
163                self.lineEditRightMotorPort.setText(   \
164                   configuration.NXT_MOTOR_PORT_RIGHT.upper() )
165                self.checkBoxMotorSpinReversed.setChecked( \
166                   configuration.NXT_MOTORS_MOUNTED_BACKWARDS)
167       
168       
169        ##################################################################
170       
171        def getMinimumThreshold(self, threshold):
172               
173                '''Return the minimum detection level which results
174                in a non-zero power setting'''
175               
176                minimum = 100
177               
178                threshold_keys = threshold.keys()
179                threshold_keys.sort()
180                threshold_keys.reverse()
181               
182                for key in threshold_keys:
183                       
184                        if ((threshold[key] < minimum) and \
185                                 (threshold[key] > 0)):
186                                minimum = key
187               
188               
189                return(minimum)
190       
191       
192        ##################################################################
193       
194        def configureNetworkBrainstorms(self):
195               
196                bluetooth_device = str(self.comboBoxNXTPortSelect.currentText())
197               
198                self.brainstormsClient = \
199                   brainstorms_client.puzzlebox_brainstorms_network_client( \
200                           self.log, \
201                           bluetooth_device=bluetooth_device, \
202                           parent=self)
203               
204                self.brainstormsClient.sendCommand('connect', \
205                                                   bluetooth_device=bluetooth_device)
206       
207       
208        ##################################################################
209       
210        def connectToBrainstormsServer(self):
211               
212                # Prevent attempting to connect to a device which no longer exists
213                if (sys.platform != 'win32'):
214                        device = str(self.comboBoxNXTPortSelect.currentText())
215                        if ((not device.startswith(DEVICE_PATH)) or \
216                            (not os.path.exists(device))):
217                                self.searchForDevices()
218                                return
219               
220               
221                if self.DEBUG:
222                        print "<---- [%s] Connecting to Brainstorms Server" % self.name
223               
224                self.configureNetworkBrainstorms()
225               
226                #if (self.brainstormsClient.socket.state() != QtNetwork.QAbstractSocket.ConnectedState):
227                        #QtGui.QMessageBox.information(self, \
228                                                                #self.brainstormsClient.socket.name, \
229                                           #"Failed to connect to Brainstorms socket server")
230               
231                #else:
232                self.disconnect(self.pushButtonNXTConnect, \
233                                                        QtCore.SIGNAL("clicked()"), \
234                                                        self.connectToBrainstormsServer)
235               
236                self.connect(self.pushButtonNXTConnect, \
237                                                        QtCore.SIGNAL("clicked()"), \
238                                                        self.disconnectFromBrainstormsServer)
239               
240                self.textLabelNXTStatus.setText("Status: Connected")
241                self.pushButtonNXTConnect.setText('Disconnect')
242               
243                self.comboBoxNXTPortSelect.setEnabled(False)
244                self.pushButtonNXTSearch.setEnabled(False)
245               
246                self.pushButtonTurnLeft.setEnabled(True)
247                self.pushButtonForward.setEnabled(True)
248                self.pushButtonTurnRight.setEnabled(True)
249                self.pushButtonTurnLeftReverse.setEnabled(True)
250                self.pushButtonReverse.setEnabled(True)
251                self.pushButtonTurnRightReverse.setEnabled(True)
252               
253                self.pushButtonNXTMessageOne.setEnabled(True)
254                self.pushButtonNXTMessageTwo.setEnabled(True)
255                self.pushButtonNXTMessageThree.setEnabled(True)
256                self.pushButtonNXTMessageFour.setEnabled(True)
257                self.pushButtonNXTMessageFive.setEnabled(True)
258                self.pushButtonNXTMessageSix.setEnabled(True)
259               
260                self.pushButtonConcentrationEnable.setEnabled(True)
261                self.pushButtonRelaxationEnable.setEnabled(True)
262                self.pushButtonSpeedEnable.setEnabled(True)
263               
264                self.pushButtonMessageOne.setEnabled(True)
265                self.pushButtonMessageTwo.setEnabled(True)
266                self.pushButtonMessageThree.setEnabled(True)
267                self.pushButtonMessageFour.setEnabled(True)
268                self.pushButtonMessageFive.setEnabled(True)
269                self.pushButtonMessageSix.setEnabled(True)
270               
271                self.pushButtonHelicopterConcentrationEnable.setEnabled(True)
272                self.pushButtonHelicopterRelaxationEnable.setEnabled(True)
273                self.pushButtonHelicopterSpeedEnable.setEnabled(True)
274       
275       
276        ##################################################################
277       
278        def disconnectFromBrainstormsServer(self):
279               
280                if self.DEBUG:
281                        print "- - [%s] Disconnecting from Brainstorms Server" % self.name
282               
283                self.stopMotors()
284               
285                # Ensure the stopMotors command has been received by the server
286                # so the NXT robot will stop before the client disconnects
287                self.brainstormsClient.socket.flush()
288               
289                self.brainstormsClient.socket.disconnectFromHost()
290               
291                self.disconnect(self.pushButtonNXTConnect, \
292                                  QtCore.SIGNAL("clicked()"), \
293                                  self.disconnectFromBrainstormsServer)
294               
295                self.connect(self.pushButtonNXTConnect, \
296                                  QtCore.SIGNAL("clicked()"), \
297                                  self.connectToBrainstormsServer)
298               
299                self.textLabelNXTStatus.setText("Status: Disconnected")
300                self.pushButtonNXTConnect.setText('Connect')
301               
302                self.comboBoxNXTPortSelect.setEnabled(True)
303                self.pushButtonNXTSearch.setEnabled(True)
304               
305                self.pushButtonTurnLeft.setEnabled(False)
306                self.pushButtonForward.setEnabled(False)
307                self.pushButtonTurnRight.setEnabled(False)
308                self.pushButtonTurnLeftReverse.setEnabled(False)
309                self.pushButtonReverse.setEnabled(False)
310                self.pushButtonTurnRightReverse.setEnabled(False)
311               
312                self.pushButtonNXTMessageOne.setEnabled(False)
313                self.pushButtonNXTMessageTwo.setEnabled(False)
314                self.pushButtonNXTMessageThree.setEnabled(False)
315                self.pushButtonNXTMessageFour.setEnabled(False)
316                self.pushButtonNXTMessageFive.setEnabled(False)
317                self.pushButtonNXTMessageSix.setEnabled(False)
318               
319                self.pushButtonConcentrationEnable.setEnabled(False)
320                self.pushButtonRelaxationEnable.setEnabled(False)
321                self.pushButtonSpeedEnable.setEnabled(False)
322               
323                self.pushButtonMessageOne.setEnabled(False)
324                self.pushButtonMessageTwo.setEnabled(False)
325                self.pushButtonMessageThree.setEnabled(False)
326                self.pushButtonMessageFour.setEnabled(False)
327                self.pushButtonMessageFive.setEnabled(False)
328                self.pushButtonMessageSix.setEnabled(False)
329               
330                self.brainstormsClient = None
331               
332                self.searchForDevices()
333       
334       
335        ##################################################################
336       
337        def connectToThinkGearHost(self):
338               
339                if self.DEBUG:
340                        print "Connecting to ThinkGear Host"
341               
342                server_host = str(self.lineEditThinkGearHost.text())
343                server_port = int(self.lineEditThinkGearPort.text())
344               
345                self.thinkgearClient = \
346                   thinkgear_client.puzzlebox_brainstorms_network_client_thinkgear( \
347                           self.log, \
348                           server_host=server_host, \
349                           server_port=server_port, \
350                           DEBUG=0, \
351                           parent=self)
352               
353                if (self.thinkgearClient.socket.state() != QtNetwork.QAbstractSocket.ConnectedState):
354                        QtGui.QMessageBox.information(self, \
355                                                                self.thinkgearClient.socket.name, \
356                                           "Failed to connect to ThinkGear socket server")
357               
358                else:
359                        self.disconnect(self.pushButtonThinkGearConnect, \
360                                                         QtCore.SIGNAL("clicked()"), \
361                                                         self.connectToThinkGearHost)
362                       
363                        self.connect(self.pushButtonThinkGearConnect, \
364                                                         QtCore.SIGNAL("clicked()"), \
365                                                         self.disconnectFromThinkGearHost)
366                       
367                        self.pushButtonThinkGearConnect.setText('Disconnect')
368                       
369                        self.comboBoxEEGHeadsetModel.setEnabled(False)
370                        self.comboBoxEEGSource.setEnabled(False)
371                        self.lineEditThinkGearHost.setEnabled(False)
372                        self.lineEditThinkGearPort.setEnabled(False)
373       
374       
375        ##################################################################
376       
377        def disconnectFromThinkGearHost(self):
378               
379                if self.DEBUG:
380                        print "Disconnecting from ThinkGear Host"
381               
382                self.thinkgearClient.disconnectFromHost()
383               
384                self.disconnect(self.pushButtonThinkGearConnect, \
385                                  QtCore.SIGNAL("clicked()"), \
386                                  self.disconnectFromThinkGearHost)
387               
388                self.connect(self.pushButtonThinkGearConnect, \
389                                  QtCore.SIGNAL("clicked()"), \
390                                  self.connectToThinkGearHost)
391               
392                self.pushButtonForward.emit(QtCore.SIGNAL("released()"))
393               
394                self.pushButtonThinkGearConnect.setText('Connect')
395               
396                self.comboBoxEEGHeadsetModel.setEnabled(True)
397                self.comboBoxEEGSource.setEnabled(True)
398                self.lineEditThinkGearHost.setEnabled(True)
399                self.lineEditThinkGearPort.setEnabled(True)
400               
401                self.progressBarConcentration.setValue(0)
402                self.progressBarRelaxation.setValue(0)
403                self.progressBarSpeed.setValue(0)
404       
405                self.progressBarHelicopterConcentration.setValue(0)
406                self.progressBarHelicopterRelaxation.setValue(0)
407                self.progressBarHelicopterSpeed.setValue(0)
408       
409                self.progressBarWheelchairConcentration.setValue(0)
410                self.progressBarWheelchairRelaxation.setValue(0)
411                self.progressBarWheelchairSpeed.setValue(0)
412       
413       
414        ##################################################################
415       
416        def connectToRCHelicopter(self):
417               
418                device_selection = str(self.comboBoxHelicopterPortSelect.currentText())
419               
420                self.helicopter = \
421                   helicopter_control.puzzlebox_brainstorms_helicopter_control( \
422                      device_address=device_selection,
423                      command='neutral', \
424                      DEBUG=self.DEBUG)
425               
426                self.helicopter.start()
427               
428                self.disconnect(self.pushButtonHelicopterConnect, \
429                                  QtCore.SIGNAL("clicked()"), \
430                                  self.connectToRCHelicopter)
431               
432                self.connect(self.pushButtonHelicopterConnect, \
433                                  QtCore.SIGNAL("clicked()"), \
434                                  self.disconnectFromRCHelicopter)
435               
436                self.pushButtonHelicopterConnect.setText('Disconnect')
437               
438                self.comboBoxHelicopterTransmitter.setEnabled(False)
439                self.comboBoxHelicopterPortSelect.setEnabled(False)
440                self.pushButtonHelicopterSearch.setEnabled(False)
441               
442                self.pushButtonHelicopterHover.setEnabled(True)
443                self.pushButtonHelicopterFlyForward.setEnabled(True)
444                self.pushButtonHelicopterLand.setEnabled(True)
445                self.pushButtonHelicopterThrottle.setEnabled(True)
446                self.verticalSliderHelicopterThrottle.setEnabled(True)
447                self.pushButtonHelicopterElevatorForward.setEnabled(True)
448                self.verticalSliderHelicopterElevatorForward.setEnabled(True)
449                self.pushButtonHelicopterElevatorReverse.setEnabled(True)
450                self.verticalSliderHelicopterElevatorReverse.setEnabled(True)
451                self.pushButtonHelicopterRudderLeft.setEnabled(True)
452                self.horizontalSliderHelicopterRudderLeft.setEnabled(True)
453                self.pushButtonHelicopterRudderRight.setEnabled(True)
454                self.horizontalSliderHelicopterRudderRight.setEnabled(True)
455                self.pushButtonHelicopterAileronLeft.setEnabled(True)
456                self.horizontalSliderHelicopterAileronLeft.setEnabled(True)
457                self.pushButtonHelicopterAileronRight.setEnabled(True)
458                self.horizontalSliderHelicopterAileronRight.setEnabled(True)
459       
460       
461        ##################################################################
462       
463        def disconnectFromRCHelicopter(self):
464               
465                self.helicopter.neutral()
466               
467                self.helicopter.stop()
468               
469                self.disconnect(self.pushButtonHelicopterConnect, \
470                                  QtCore.SIGNAL("clicked()"), \
471                                  self.disconnectFromRCHelicopter)
472               
473                self.connect(self.pushButtonHelicopterConnect, \
474                                  QtCore.SIGNAL("clicked()"), \
475                                  self.connectToRCHelicopter)
476               
477                self.pushButtonHelicopterConnect.setText('Connect')
478               
479                self.comboBoxHelicopterTransmitter.setEnabled(True)
480                self.comboBoxHelicopterPortSelect.setEnabled(True)
481                self.pushButtonHelicopterSearch.setEnabled(True)
482               
483                self.pushButtonHelicopterHover.setEnabled(False)
484                self.pushButtonHelicopterFlyForward.setEnabled(False)
485                self.pushButtonHelicopterLand.setEnabled(False)
486                self.pushButtonHelicopterThrottle.setEnabled(False)
487                self.verticalSliderHelicopterThrottle.setEnabled(False)
488                self.pushButtonHelicopterElevatorForward.setEnabled(False)
489                self.verticalSliderHelicopterElevatorForward.setEnabled(False)
490                self.pushButtonHelicopterElevatorReverse.setEnabled(False)
491                self.verticalSliderHelicopterElevatorReverse.setEnabled(False)
492                self.pushButtonHelicopterRudderLeft.setEnabled(False)
493                self.horizontalSliderHelicopterRudderLeft.setEnabled(False)
494                self.pushButtonHelicopterRudderRight.setEnabled(False)
495                self.horizontalSliderHelicopterRudderRight.setEnabled(False)
496                self.pushButtonHelicopterAileronLeft.setEnabled(False)
497                self.horizontalSliderHelicopterAileronLeft.setEnabled(False)
498                self.pushButtonHelicopterAileronRight.setEnabled(False)
499                self.horizontalSliderHelicopterAileronRight.setEnabled(False)
500       
501       
502        ##################################################################
503       
504        def connectToWheelchair(self):
505               
506                self.disconnect(self.pushButtonWheelchairConnect, \
507                                  QtCore.SIGNAL("clicked()"), \
508                                  self.connectToWheelchair)
509               
510                self.connect(self.pushButtonWheelchairConnect, \
511                                  QtCore.SIGNAL("clicked()"), \
512                                  self.disconnectFromWheelchair)
513               
514                self.pushButtonWheelchairConnect.setText('Disconnect')
515               
516                self.comboBoxWheelchairTransmitter.setEnabled(False)
517                self.comboBoxWheelchairPortSelect.setEnabled(False)
518                self.pushButtonWheelchairSearch.setEnabled(False)
519               
520                self.pushButtonWheelchairForward.setEnabled(True)
521                self.pushButtonWheelchairReverse.setEnabled(True)
522                self.pushButtonWheelchairLeft.setEnabled(True)
523                self.pushButtonWheelchairRight.setEnabled(True)
524                self.pushButtonWheelchairStop.setEnabled(True)
525                self.dialWheelchairSpeed.setEnabled(True)
526       
527       
528        ##################################################################
529       
530        def disconnectFromWheelchair(self):
531               
532                self.disconnect(self.pushButtonWheelchairConnect, \
533                                  QtCore.SIGNAL("clicked()"), \
534                                  self.disconnectFromWheelchair)
535               
536                self.connect(self.pushButtonWheelchairConnect, \
537                                  QtCore.SIGNAL("clicked()"), \
538                                  self.connectToWheelchair)
539               
540                self.pushButtonWheelchairConnect.setText('Connect')
541               
542                self.comboBoxWheelchairTransmitter.setEnabled(True)
543                self.comboBoxWheelchairPortSelect.setEnabled(True)
544                self.pushButtonWheelchairSearch.setEnabled(True)
545               
546                self.pushButtonWheelchairForward.setEnabled(False)
547                self.pushButtonWheelchairReverse.setEnabled(False)
548                self.pushButtonWheelchairLeft.setEnabled(False)
549                self.pushButtonWheelchairRight.setEnabled(False)
550                self.pushButtonWheelchairStop.setEnabled(False)
551                self.dialWheelchairSpeed.setEnabled(False)
552       
553       
554        ##################################################################
555       
556        def updateConcentrationButton(self):
557               
558                if self.pushButtonConcentrationEnable.isChecked():
559                       
560                        self.pushButtonConcentrationEnable.setText('Enabled')
561               
562                else:
563                       
564                        self.pushButtonConcentrationEnable.setText('Disabled')
565                        self.progressBarConcentration.setValue(0)
566               
567               
568                self.updateSpeed()
569       
570       
571        ##################################################################
572       
573        def updateRelaxationButton(self):
574               
575                if self.pushButtonRelaxationEnable.isChecked():
576               
577                        self.pushButtonRelaxationEnable.setText('Enabled')
578               
579                else:
580                       
581                        self.pushButtonRelaxationEnable.setText('Disabled')
582                        self.progressBarRelaxation.setValue(0)
583               
584               
585                self.updateNXTSpeed()
586       
587       
588        ##################################################################
589       
590        def updateSpeedButton(self):
591               
592                if self.pushButtonSpeedEnable.isChecked():
593               
594                        self.pushButtonSpeedEnable.setText('Enabled')
595                        self.updateSpeed()
596               
597                else:
598                       
599                        self.pushButtonSpeedEnable.setText('Disabled')
600                        self.progressBarSpeed.setValue(0)
601                        self.stopMotors()
602       
603       
604        ##################################################################
605       
606        def updateHelicopterConcentrationButton(self):
607               
608                if self.pushButtonHelicopterConcentrationEnable.isChecked():
609                       
610                        self.pushButtonHelicopterConcentrationEnable.setText('Enabled')
611               
612                else:
613                       
614                        self.pushButtonHelicopterConcentrationEnable.setText('Disabled')
615                        self.progressBarHelicopterConcentration.setValue(0)
616               
617               
618                self.updateHelicopterSpeed()
619       
620       
621        ##################################################################
622       
623        def updateHelicopterRelaxationButton(self):
624               
625                if self.pushButtonHelicopterRelaxationEnable.isChecked():
626               
627                        self.pushButtonHelicopterRelaxationEnable.setText('Enabled')
628               
629                else:
630                       
631                        self.pushButtonHelicopterRelaxationEnable.setText('Disabled')
632                        self.progressBarHelicopterRelaxation.setValue(0)
633               
634               
635                self.updateHelicopterSpeed()
636       
637       
638        ##################################################################
639       
640        def updateHelicopterSpeedButton(self):
641               
642                if self.pushButtonHelicopterSpeedEnable.isChecked():
643               
644                        self.pushButtonHelicopterSpeedEnable.setText('Enabled')
645                        self.updateHelicopterSpeed()
646               
647                else:
648                       
649                        self.pushButtonHelicopterSpeedEnable.setText('Disabled')
650                        self.progressBarHelicopterSpeed.setValue(0)
651                        self.stopMotors()
652       
653       
654        ##################################################################
655       
656        def updateWheelchairConcentrationButton(self):
657               
658                if self.pushButtonWheelchairConcentrationEnable.isChecked():
659                       
660                        self.pushButtonWheelchairConcentrationEnable.setText('Enabled')
661               
662                else:
663                       
664                        self.pushButtonWheelchairConcentrationEnable.setText('Disabled')
665                        self.progressBarWheelchairConcentration.setValue(0)
666               
667               
668                self.updateWheelchairSpeed()
669       
670       
671        ##################################################################
672       
673        def updateWheelchairRelaxationButton(self):
674               
675                if self.pushButtonWheelchairRelaxationEnable.isChecked():
676               
677                        self.pushButtonWheelchairRelaxationEnable.setText('Enabled')
678               
679                else:
680                       
681                        self.pushButtonWheelchairRelaxationEnable.setText('Disabled')
682                        self.progressBarWheelchairRelaxation.setValue(0)
683               
684               
685                self.updateWheelchairSpeed()
686       
687       
688        ##################################################################
689       
690        def updateWheelchairSpeedButton(self):
691               
692                if self.pushButtonWheelchairSpeedEnable.isChecked():
693               
694                        self.pushButtonWheelchairSpeedEnable.setText('Enabled')
695                        self.updateWheelchairSpeed()
696               
697                else:
698                       
699                        self.pushButtonWheelchairSpeedEnable.setText('Disabled')
700                        self.progressBarWheelchairSpeed.setValue(0)
701                        self.stopMotors()
702       
703       
704        ##################################################################
705       
706        def connectWidgets(self):
707               
708                # LEGO Mindstorms Buttons
709                self.connect(self.pushButtonTurnLeft, QtCore.SIGNAL("pressed()"), \
710                             self.turnLeft)
711                self.connect(self.pushButtonTurnLeft, QtCore.SIGNAL("released()"), \
712                             self.stopMotors)
713               
714                self.connect(self.pushButtonForward, QtCore.SIGNAL("pressed()"), \
715                             self.driveForward)
716                self.connect(self.pushButtonForward, QtCore.SIGNAL("released()"), \
717                             self.stopMotors)
718               
719                self.connect(self.pushButtonTurnRight, QtCore.SIGNAL("pressed()"), \
720                             self.turnRight)
721                self.connect(self.pushButtonTurnRight, QtCore.SIGNAL("released()"), \
722                             self.stopMotors)
723               
724                self.connect(self.pushButtonTurnLeftReverse, QtCore.SIGNAL("pressed()"), \
725                             self.turnLeftInReverse)
726                self.connect(self.pushButtonTurnLeftReverse, QtCore.SIGNAL("released()"), \
727                             self.stopMotors)
728               
729                self.connect(self.pushButtonReverse, QtCore.SIGNAL("pressed()"), \
730                             self.driveReverse)
731                self.connect(self.pushButtonReverse, QtCore.SIGNAL("released()"), \
732                             self.stopMotors)
733               
734                self.connect(self.pushButtonTurnRightReverse, QtCore.SIGNAL("pressed()"), \
735                             self.turnRightInReverse)
736                self.connect(self.pushButtonTurnRightReverse, QtCore.SIGNAL("released()"), \
737                             self.stopMotors)
738               
739               
740                self.connect(self.pushButtonNXTSearch, \
741                                  QtCore.SIGNAL("clicked()"), \
742                                  self.searchForDevices)
743               
744                self.connect(self.pushButtonNXTConnect, \
745                                  QtCore.SIGNAL("clicked()"), \
746                                  self.connectToBrainstormsServer)
747               
748               
749                self.connect(self.pushButtonConcentrationEnable, \
750                                  QtCore.SIGNAL("clicked()"), \
751                                  self.updateConcentrationButton)
752               
753                self.connect(self.pushButtonRelaxationEnable, \
754                                  QtCore.SIGNAL("clicked()"), \
755                                  self.updateRelaxationButton)
756               
757                self.connect(self.pushButtonSpeedEnable, \
758                                  QtCore.SIGNAL("clicked()"), \
759                                  self.updateSpeedButton)
760               
761               
762                self.connect(self.pushButtonNXTMessageOne, QtCore.SIGNAL("pressed()"), \
763                             self.sendMessageOne)
764               
765                self.connect(self.pushButtonNXTMessageTwo, QtCore.SIGNAL("pressed()"), \
766                             self.sendMessageTwo)
767               
768                self.connect(self.pushButtonNXTMessageThree, QtCore.SIGNAL("pressed()"), \
769                             self.sendMessageThree)
770               
771                self.connect(self.pushButtonNXTMessageFour, QtCore.SIGNAL("pressed()"), \
772                             self.sendMessageFour)
773               
774                self.connect(self.pushButtonNXTMessageFive, QtCore.SIGNAL("pressed()"), \
775                             self.sendMessageFive)
776               
777                self.connect(self.pushButtonNXTMessageSix, QtCore.SIGNAL("pressed()"), \
778                             self.sendMessageSix)
779               
780               
781               
782                # RC Helicopter Buttons
783                self.connect(self.pushButtonHelicopterSearch, \
784                                  QtCore.SIGNAL("clicked()"), \
785                                  self.searchForDevices)
786               
787                self.connect(self.pushButtonHelicopterConnect, \
788                                  QtCore.SIGNAL("clicked()"), \
789                                  self.connectToRCHelicopter)
790               
791               
792                self.connect(self.pushButtonHelicopterConcentrationEnable, \
793                                  QtCore.SIGNAL("clicked()"), \
794                                  self.updateHelicopterConcentrationButton)
795               
796                self.connect(self.pushButtonHelicopterRelaxationEnable, \
797                                  QtCore.SIGNAL("clicked()"), \
798                                  self.updateHelicopterRelaxationButton)
799               
800                self.connect(self.pushButtonHelicopterSpeedEnable, \
801                                  QtCore.SIGNAL("clicked()"), \
802                                  self.updateHelicopterSpeedButton)
803               
804               
805                self.connect(self.pushButtonHelicopterHover, \
806                                  QtCore.SIGNAL("clicked()"), \
807                                  self.enableHelicopterHover)
808               
809                self.connect(self.pushButtonHelicopterFlyForward, \
810                                  QtCore.SIGNAL("clicked()"), \
811                                  self.enableHelicopterFlyForward)
812               
813                self.connect(self.pushButtonHelicopterLand, \
814                                  QtCore.SIGNAL("clicked()"), \
815                                  self.landHelicopter)
816               
817               
818               
819                # Wheelchair Buttons
820                self.connect(self.pushButtonWheelchairSearch, \
821                                  QtCore.SIGNAL("clicked()"), \
822                                  self.searchForDevices)
823               
824                self.connect(self.pushButtonWheelchairConnect, \
825                                  QtCore.SIGNAL("clicked()"), \
826                                  self.connectToWheelchair)
827               
828               
829                self.connect(self.pushButtonWheelchairConcentrationEnable, \
830                                  QtCore.SIGNAL("clicked()"), \
831                                  self.updateWheelchairConcentrationButton)
832               
833                self.connect(self.pushButtonWheelchairRelaxationEnable, \
834                                  QtCore.SIGNAL("clicked()"), \
835                                  self.updateWheelchairRelaxationButton)
836               
837                self.connect(self.pushButtonWheelchairSpeedEnable, \
838                                  QtCore.SIGNAL("clicked()"), \
839                                  self.updateWheelchairSpeedButton)
840               
841               
842                self.connect(self.pushButtonWheelchairForward, \
843                                  QtCore.SIGNAL("clicked()"), \
844                                  self.driveWheelchairForward)
845               
846                self.connect(self.pushButtonWheelchairReverse, \
847                                  QtCore.SIGNAL("clicked()"), \
848                                  self.driveWheelchairReverse)
849               
850                self.connect(self.pushButtonWheelchairLeft, \
851                                  QtCore.SIGNAL("clicked()"), \
852                                  self.driveWheelchairLeft)
853               
854                self.connect(self.pushButtonWheelchairRight, \
855                                  QtCore.SIGNAL("clicked()"), \
856                                  self.driveWheelchairRight)
857               
858                self.connect(self.pushButtonWheelchairStop, \
859                                  QtCore.SIGNAL("clicked()"), \
860                                  self.stopWheelchair)
861               
862               
863               
864                # Control Panel Buttons
865                self.connect(self.pushButtonMessageOne, QtCore.SIGNAL("pressed()"), \
866                             self.sendMessageOne)
867               
868                self.connect(self.pushButtonMessageTwo, QtCore.SIGNAL("pressed()"), \
869                             self.sendMessageTwo)
870               
871                self.connect(self.pushButtonMessageThree, QtCore.SIGNAL("pressed()"), \
872                             self.sendMessageThree)
873               
874                self.connect(self.pushButtonMessageFour, QtCore.SIGNAL("pressed()"), \
875                             self.sendMessageFour)
876               
877                self.connect(self.pushButtonMessageFive, QtCore.SIGNAL("pressed()"), \
878                             self.sendMessageFive)
879               
880                self.connect(self.pushButtonMessageSix, QtCore.SIGNAL("pressed()"), \
881                             self.sendMessageSix)
882               
883               
884                self.connect(self.pushButtonThinkGearConnect, \
885                                  QtCore.SIGNAL("clicked()"), \
886                                  self.connectToThinkGearHost)
887               
888                self.connect(self.pushButtonSendFeedback, \
889                                  QtCore.SIGNAL("clicked()"), \
890                                  self.sendFeedback)
891               
892               
893                #shortcut = QtGui.QShortcut(self)
894                #shortcut.setKey(tr("Down"))
895                #self.connect(shortcut, QtCore.SIGNAL("pressed()"), self.driveReverse)
896               
897               
898                action = QtGui.QAction(self)
899                action.setShortcut(QtGui.QKeySequence("W"))
900                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonForward, QtCore.SLOT("animateClick()"))
901                self.addAction(action)
902               
903                action = QtGui.QAction(self)
904                action.setShortcut(QtGui.QKeySequence("Up"))
905                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonForward, QtCore.SLOT("animateClick()"))
906                self.addAction(action)
907               
908               
909                action = QtGui.QAction(self)
910                action.setShortcut(QtGui.QKeySequence("Left"))
911                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnLeft, QtCore.SLOT("animateClick()"))
912                self.addAction(action)
913               
914                action = QtGui.QAction(self)
915                action.setShortcut(QtGui.QKeySequence("A"))
916                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnLeft, QtCore.SLOT("animateClick()"))
917                self.addAction(action)
918               
919               
920                action = QtGui.QAction(self)
921                action.setShortcut(QtGui.QKeySequence("S"))
922                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonReverse, QtCore.SLOT("animateClick()"))
923                self.addAction(action)
924               
925                action = QtGui.QAction(self)
926                action.setShortcut(QtGui.QKeySequence("Down"))
927                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonReverse, QtCore.SLOT("animateClick()"))
928                self.addAction(action)
929               
930               
931                action = QtGui.QAction(self)
932                action.setShortcut(QtGui.QKeySequence("D"))
933                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnRight, QtCore.SLOT("animateClick()"))
934                self.addAction(action)
935               
936                action = QtGui.QAction(self)
937                action.setShortcut(QtGui.QKeySequence("Right"))
938                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnRight, QtCore.SLOT("animateClick()"))
939                self.addAction(action)
940               
941               
942                action = QtGui.QAction(self)
943                action.setShortcut(QtGui.QKeySequence("Z"))
944                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnLeftReverse, QtCore.SLOT("animateClick()"))
945                self.addAction(action)
946               
947               
948                action = QtGui.QAction(self)
949                action.setShortcut(QtGui.QKeySequence("C"))
950                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnRightReverse, QtCore.SLOT("animateClick()"))
951                self.addAction(action)
952               
953               
954               
955                # RC Helicopter Buttons
956               
957                action = QtGui.QAction(self)
958                action.setShortcut(QtGui.QKeySequence("Home"))
959                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonHelicopterHover, QtCore.SLOT("animateClick()"))
960                self.addAction(action)
961                action = QtGui.QAction(self)
962                action.setShortcut(QtGui.QKeySequence("["))
963                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonHelicopterHover, QtCore.SLOT("animateClick()"))
964                self.addAction(action)
965               
966                action = QtGui.QAction(self)
967                action.setShortcut(QtGui.QKeySequence("PgUp"))
968                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonHelicopterFlyForward, QtCore.SLOT("animateClick()"))
969                self.addAction(action)
970                action = QtGui.QAction(self)
971                action.setShortcut(QtGui.QKeySequence("]"))
972                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonHelicopterFlyForward, QtCore.SLOT("animateClick()"))
973                self.addAction(action)
974               
975                action = QtGui.QAction(self)
976                action.setShortcut(QtGui.QKeySequence("End"))
977                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonHelicopterLand, QtCore.SLOT("animateClick()"))
978                self.addAction(action)
979                action = QtGui.QAction(self)
980                action.setShortcut(QtGui.QKeySequence("\\"))
981                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonHelicopterLand, QtCore.SLOT("animateClick()"))
982                self.addAction(action)
983               
984               
985               
986                # Wheelchair Buttons
987               
988                action = QtGui.QAction(self)
989                action.setShortcut(QtGui.QKeySequence("i"))
990                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairForward, QtCore.SLOT("animateClick()"))
991                self.addAction(action)
992               
993                action = QtGui.QAction(self)
994                action.setShortcut(QtGui.QKeySequence("k"))
995                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairReverse, QtCore.SLOT("animateClick()"))
996                self.addAction(action)
997               
998                action = QtGui.QAction(self)
999                action.setShortcut(QtGui.QKeySequence("j"))
1000                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairLeft, QtCore.SLOT("animateClick()"))
1001                self.addAction(action)
1002               
1003                action = QtGui.QAction(self)
1004                action.setShortcut(QtGui.QKeySequence("l"))
1005                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairRight, QtCore.SLOT("animateClick()"))
1006                self.addAction(action)
1007               
1008                action = QtGui.QAction(self)
1009                action.setShortcut(QtGui.QKeySequence("Space"))
1010                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairStop, QtCore.SLOT("animateClick()"))
1011                self.addAction(action)
1012               
1013               
1014               
1015                # Control Panel Buttons
1016               
1017                action = QtGui.QAction(self)
1018                action.setShortcut(QtGui.QKeySequence("1"))
1019                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageOne, QtCore.SLOT("animateClick()"))
1020                self.addAction(action)
1021               
1022                action = QtGui.QAction(self)
1023                action.setShortcut(QtGui.QKeySequence("2"))
1024                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageTwo, QtCore.SLOT("animateClick()"))
1025                self.addAction(action)
1026               
1027                action = QtGui.QAction(self)
1028                action.setShortcut(QtGui.QKeySequence("3"))
1029                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageThree, QtCore.SLOT("animateClick()"))
1030                self.addAction(action)
1031               
1032                action = QtGui.QAction(self)
1033                action.setShortcut(QtGui.QKeySequence("4"))
1034                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageFour, QtCore.SLOT("animateClick()"))
1035                self.addAction(action)
1036               
1037                action = QtGui.QAction(self)
1038                action.setShortcut(QtGui.QKeySequence("5"))
1039                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageFive, QtCore.SLOT("animateClick()"))
1040                self.addAction(action)
1041               
1042                action = QtGui.QAction(self)
1043                action.setShortcut(QtGui.QKeySequence("6"))
1044                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageSix, QtCore.SLOT("animateClick()"))
1045                self.addAction(action)
1046               
1047               
1048                #self.pushButtonForward.setAutoRepeat(False)
1049                #self.pushButtonForward.setAutoRepeatDelay(0)
1050                #self.pushButtonForward.setAutoRepeatInterval(0)
1051       
1052       
1053        ##################################################################
1054       
1055        def searchForDevices(self):
1056               
1057                nxt_devices = []
1058                rc_helicopter_devices = []
1059                wheelchair_devices = []
1060               
1061                #if (sys.platform != 'win32'):
1062                if False: # temporarily disabled
1063                       
1064                        # Bluetooth module doesn't compile properly under Windows
1065                       
1066                        bluetooth_devices = []
1067                       
1068                        try:
1069                                bluetooth_devices = bluetooth.discover_devices( \
1070                                                       duration=5, \
1071                                                       flush_cache=True, \
1072                                                       lookup_names=False)
1073                        except:
1074                                #command = '%s con' % PATH_TO_HCITOOL
1075                                command = '%s scan' % PATH_TO_HCITOOL
1076                               
1077                                output = os.popen(command, 'r')
1078                               
1079                                for line in output.readlines():
1080                                        print line
1081                                        try:
1082                                                address = line.split(' ')[2]
1083                                        except:
1084                                                pass
1085                                        else:
1086                                                bluetooth_devices.append(address)
1087                       
1088                        for address in bluetooth_devices:
1089                                device_name = bluetooth.lookup_name(address)
1090                                if ((device_name == 'NXT') and \
1091                                    (address not in nxt_devices)):
1092                                        nxt_devices.append(address)
1093                       
1094                       
1095                        if self.DEBUG:
1096                                print "Bluetooth NXT devices found:",
1097                                print nxt_devices
1098               
1099               
1100                # List all serial devices
1101                serial_devices = self.enumerateSerialPorts()
1102               
1103                for serial_device in serial_devices:
1104                        #serial_device = self.fullPortName(serial_device)
1105                        nxt_devices.append(serial_device)
1106                        rc_helicopter_devices.append(serial_device)
1107                        wheelchair_devices.append(serial_device)
1108               
1109               
1110                # Configure combo boxes
1111                if nxt_devices == []:
1112                        nxt_devices.append('N/A')
1113               
1114                if rc_helicopter_devices == []:
1115                        rc_helicopter_devices.append('N/A')
1116               
1117                if wheelchair_devices == []:
1118                        wheelchair_devices.append('N/A')
1119               
1120               
1121                # Don't reset combo boxes if already connected
1122                if self.pushButtonNXTConnect.text != 'Disconnect':
1123                       
1124                        self.comboBoxNXTPortSelect.clear()
1125                       
1126                        #nxt_devices.reverse()
1127                        for nxt_device in nxt_devices:
1128                                self.comboBoxNXTPortSelect.addItem(nxt_device)
1129               
1130               
1131                if self.pushButtonHelicopterConnect.text != 'Disconnect':
1132                       
1133                        self.comboBoxHelicopterPortSelect.clear()
1134                       
1135                        #rc_helicopter_devices.reverse()
1136                        for rc_helicopter in rc_helicopter_devices:
1137                                self.comboBoxHelicopterPortSelect.addItem(rc_helicopter)
1138       
1139       
1140                if self.pushButtonWheelchairConnect.text != 'Disconnect':
1141                       
1142                        self.comboBoxWheelchairPortSelect.clear()
1143                       
1144                        #rc_helicopter_devices.reverse()
1145                        for wheelchair in wheelchair_devices:
1146                                self.comboBoxWheelchairPortSelect.addItem(wheelchair)
1147       
1148       
1149        ##################################################################
1150       
1151        def enumerateSerialPorts(self):
1152               
1153                """ Uses the Win32 registry to return an
1154                iterator of serial (COM) ports
1155                existing on this computer.
1156               
1157                from http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/
1158                """
1159               
1160                serial_ports = []
1161               
1162                if (sys.platform == 'win32'):
1163                       
1164                        path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
1165                        try:
1166                                key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path)
1167                        except WindowsError:
1168                                #raise IterationError
1169                                #return
1170                                pass
1171                       
1172                        for i in itertools.count():
1173                                try:
1174                                        val = winreg.EnumValue(key, i)
1175                                        #yield str(val[1])
1176                                        serial_ports.append( str(val[1]) )
1177                                except EnvironmentError:
1178                                        break
1179               
1180               
1181                else:
1182                       
1183                        if os.path.exists(DEVICE_PATH):
1184                                device_list = os.listdir(DEVICE_PATH)
1185                               
1186                                device_list.sort()
1187                       
1188                                for device in device_list:
1189                                        if device.startswith('ttyUSB'):
1190                                                serial_ports.append( DEVICE_PATH + '/' + device )
1191                                for device in device_list:
1192                                        if device.startswith('rfcomm'):
1193                                                serial_ports.append( DEVICE_PATH + '/' + device )
1194                                for device in device_list:
1195                                        if device.startswith('ttyACM'):
1196                                                serial_ports.append( DEVICE_PATH + '/' + device )
1197                                for device in device_list:
1198                                        if device.startswith('ttyS'):
1199                                                serial_ports.append( DEVICE_PATH + '/' + device )
1200               
1201               
1202                return(serial_ports)
1203       
1204       
1205        ##################################################################
1206       
1207        def fullPortName(self, portname):
1208               
1209                """ Given a port-name (of the form COM7,
1210                COM12, CNCA0, etc.) returns a full
1211                name suitable for opening with the
1212                Serial class.
1213                """
1214               
1215                m = re.match('^COM(\d+)$', portname)
1216                if m and int(m.group(1)) < 10:
1217                        return portname
1218               
1219                return '\\\\.\\' + portname
1220       
1221       
1222        ##################################################################
1223       
1224        # LEGO Mindstorms Controls
1225       
1226        def turnLeft(self):
1227                self.brainstormsClient.sendCommand('turn_left')
1228                self.drive_state = 'turn_left'
1229       
1230        def driveForward(self):
1231                #if self.DEBUG:
1232                        #print "driveForward"
1233                self.pushButtonForward.setDown(True)
1234                if (self.drive_state != 'drive_forward'):
1235                        self.updateNXTSpeed(new_speed=DEFAULT_NXT_POWER_LEVEL)
1236                self.brainstormsClient.sendCommand('drive_forward', power=self.current_speed)
1237                self.drive_state = 'drive_forward'
1238       
1239        def turnRight(self):
1240                self.brainstormsClient.sendCommand('turn_right')
1241                self.drive_state = 'turn_right'
1242       
1243        def turnLeftInReverse(self):
1244                self.brainstormsClient.sendCommand('turn_left_in_reverse')
1245                self.drive_state = 'turn_left_in_reverse'
1246       
1247        def driveReverse(self):
1248                self.brainstormsClient.sendCommand('drive_reverse')
1249                self.drive_state = 'drive_reverse'
1250       
1251        def turnRightInReverse(self):
1252                self.brainstormsClient.sendCommand('turn_right_in_reverse')
1253                self.drive_state = 'turn_right_in_reverse'
1254       
1255        def stopMotors(self):
1256                self.pushButtonForward.setDown(False)
1257                if (self.current_speed != 0):
1258                        self.updateNXTSpeed(new_speed=0)
1259                if self.brainstormsClient != None:
1260                        self.brainstormsClient.sendCommand('stop_motors')
1261                self.drive_state = 'stop_motors'
1262       
1263        def sendMessageOne(self):
1264                message = str(self.lineEditMessageOne.text())
1265                self.brainstormsClient.sendCommand('send_message_1')
1266       
1267        def sendMessageTwo(self):
1268                message = str(self.lineEditMessageTwo.text())
1269                self.brainstormsClient.sendCommand('send_message_2')
1270       
1271        def sendMessageThree(self):
1272                message = str(self.lineEditMessageThree.text())
1273                self.brainstormsClient.sendCommand('send_message_3')
1274       
1275        def sendMessageFour(self):
1276                message = str(self.lineEditMessageFour.text())
1277                self.brainstormsClient.sendCommand('send_message_4')
1278       
1279        def sendMessageFive(self):
1280                message = str(self.lineEditMessageFive.text())
1281                self.brainstormsClient.sendCommand('send_message_5')
1282       
1283        def sendMessageSix(self):
1284                message = str(self.lineEditMessageSix.text())
1285                self.brainstormsClient.sendCommand('send_message_6')
1286       
1287       
1288        ##################################################################
1289       
1290        def enableHelicopterHover(self):
1291               
1292                if self.pushButtonHelicopterFlyForward.isChecked():
1293                        self.pushButtonHelicopterFlyForward.setChecked(False)
1294                        self.disableHelicopterFlyForward()
1295               
1296                self.helicopter.hover(duration=None)
1297               
1298                self.disconnect(self.pushButtonHelicopterHover, \
1299                                                        QtCore.SIGNAL("clicked()"), \
1300                                                        self.enableHelicopterHover)
1301               
1302                self.connect(self.pushButtonHelicopterHover, \
1303                                  QtCore.SIGNAL("clicked()"), \
1304                                  self.disableHelicopterHover)
1305               
1306                #if self.pushButtonHelicopterFlyForward.isChecked():
1307                        #self.pushButtonHelicopterFlyForward.toggle()
1308                        ##self.disableHelicopterFlyForward()
1309       
1310       
1311        ##################################################################
1312       
1313        def disableHelicopterHover(self):
1314               
1315                self.helicopter.neutral()
1316               
1317                self.disconnect(self.pushButtonHelicopterHover, \
1318                                                        QtCore.SIGNAL("clicked()"), \
1319                                                        self.disableHelicopterHover)
1320               
1321                self.connect(self.pushButtonHelicopterHover, \
1322                                  QtCore.SIGNAL("clicked()"), \
1323                                  self.enableHelicopterHover)
1324       
1325       
1326        ##################################################################
1327       
1328        def enableHelicopterFlyForward(self):
1329               
1330                if self.pushButtonHelicopterHover.isChecked():
1331                        self.pushButtonHelicopterHover.setChecked(False)
1332                        self.disableHelicopterHover()
1333               
1334                self.helicopter.fly_forward(duration=None)
1335               
1336                self.disconnect(self.pushButtonHelicopterFlyForward, \
1337                                                        QtCore.SIGNAL("clicked()"), \
1338                                                        self.enableHelicopterFlyForward)
1339               
1340                self.connect(self.pushButtonHelicopterFlyForward, \
1341                                  QtCore.SIGNAL("clicked()"), \
1342                                  self.disableHelicopterFlyForward)
1343               
1344                #if self.pushButtonHelicopterHover.isChecked():
1345                        #self.pushButtonHelicopterHover.toggle()
1346                        ##self.disableHelicopterHover()
1347       
1348       
1349        ##################################################################
1350       
1351        def disableHelicopterFlyForward(self):
1352               
1353                self.helicopter.neutral()
1354               
1355                self.disconnect(self.pushButtonHelicopterFlyForward, \
1356                                                        QtCore.SIGNAL("clicked()"), \
1357                                                        self.disableHelicopterFlyForward)
1358               
1359                self.connect(self.pushButtonHelicopterFlyForward, \
1360                                  QtCore.SIGNAL("clicked()"), \
1361                                  self.enableHelicopterFlyForward)
1362       
1363       
1364        ##################################################################
1365       
1366        def landHelicopter(self):
1367               
1368                self.helicopter.neutral()
1369               
1370                if self.pushButtonHelicopterHover.isChecked():
1371                        self.pushButtonHelicopterHover.setChecked(False)
1372                        self.disableHelicopterHover()
1373                if self.pushButtonHelicopterFlyForward.isChecked():
1374                        self.pushButtonHelicopterFlyForward.setChecked(False)
1375                        self.disableHelicopterFlyForward()
1376       
1377       
1378        ##################################################################
1379       
1380        def driveWheelchairForward(self):
1381                print "WheelchairForward"
1382       
1383        def driveWheelchairReverse(self):
1384                print "WheelchairReverse"
1385       
1386        def driveWheelchairLeft(self):
1387                print "WheelchairLeft"
1388       
1389        def driveWheelchairRight(self):
1390                print "WheelchairRight"
1391       
1392        def stopWheelchair(self):
1393                print "stopWheelchair"
1394       
1395       
1396        ##################################################################
1397       
1398        def updateNXTSpeed(self, new_speed=None):
1399               
1400                if new_speed == None:
1401               
1402                        concentration=self.progressBarConcentration.value()
1403                        relaxation=self.progressBarRelaxation.value()
1404                       
1405                        new_speed = self.calculateSpeed(concentration, relaxation)
1406               
1407               
1408                # Update GUI
1409                if self.pushButtonSpeedEnable.isChecked():
1410                        self.progressBarSpeed.setValue(new_speed)
1411               
1412               
1413                # If there is a change between the new and current speeds
1414                # and either the robot is currently driving forward
1415                # or the "speed control" button is enabled,
1416                # then send the updated speed to the robot
1417                if ((self.current_speed != new_speed) and \
1418                         ((self.drive_state == 'drive_forward') or \
1419                          (self.pushButtonSpeedEnable.isChecked()))):
1420                       
1421                        if (new_speed == 0):
1422                                self.current_speed = new_speed
1423                                self.stopMotors()
1424                        else:
1425                                if ((self.brainstormsClient != None) and \
1426                                    (self.pushButtonSpeedEnable.isChecked())):
1427                                        self.pushButtonForward.setDown(True)
1428                                        self.brainstormsClient.sendCommand('drive_forward', power=new_speed)
1429               
1430               
1431                self.current_speed = new_speed
1432       
1433       
1434        ##################################################################
1435       
1436        def updateHelicopterSpeed(self, new_speed=None):
1437               
1438                if new_speed == None:
1439               
1440                        concentration=self.progressBarHelicopterConcentration.value()
1441                        relaxation=self.progressBarHelicopterRelaxation.value()
1442                       
1443                        new_speed = self.calculateSpeed(concentration, relaxation)
1444               
1445               
1446                # Update GUI
1447                if self.pushButtonHelicopterSpeedEnable.isChecked():
1448                        self.progressBarHelicopterSpeed.setValue(new_speed)
1449               
1450               
1451                self.current_speed = new_speed
1452       
1453       
1454        ##################################################################
1455       
1456        def updateWheelchairSpeed(self, new_speed=None):
1457               
1458                if new_speed == None:
1459               
1460                        concentration=self.progressBarWheelchairConcentration.value()
1461                        relaxation=self.progressBarWheelchairRelaxation.value()
1462                       
1463                        new_speed = self.calculateSpeed(concentration, relaxation)
1464               
1465               
1466                # Update GUI
1467                if self.pushButtonWheelchairSpeedEnable.isChecked():
1468                        self.progressBarWheelchairSpeed.setValue(new_speed)
1469               
1470               
1471                self.current_speed = new_speed
1472       
1473        ##################################################################
1474       
1475        def calculateSpeed(self, concentration, relaxation):
1476               
1477                speed = 0
1478               
1479                thresholds = THINKGEAR_POWER_THRESHOLDS
1480               
1481                match = int(concentration)
1482               
1483                while ((match not in thresholds['concentration'].keys()) and \
1484                            (match >= 0)):
1485                        match -= 1
1486               
1487               
1488                if match in thresholds['concentration'].keys():
1489                        speed = thresholds['concentration'][match]
1490               
1491               
1492                match = int(relaxation)
1493               
1494                while ((match not in thresholds['relaxation'].keys()) and \
1495                            (match >= 0)):
1496                        match -= 1
1497               
1498                if match in thresholds['relaxation'].keys():
1499                        speed = speed + thresholds['relaxation'][match]
1500               
1501               
1502                # LEGO Mindstorms power settings cannot exceed 100
1503                # and don't drive well with levels less than 50
1504                if (speed > 100):
1505                        speed = 100
1506                elif (speed < 50):
1507                        speed = 0
1508               
1509               
1510                return(speed)
1511       
1512       
1513        ##################################################################
1514       
1515        def processPacketThinkGear(self, packet):
1516               
1517                if ('eSense' in packet.keys()):
1518                       
1519                        if ('attention' in packet['eSense'].keys()):
1520                                if self.pushButtonConcentrationEnable.isChecked():
1521                                        self.progressBarConcentration.setValue(packet['eSense']['attention'])
1522                                if self.pushButtonHelicopterConcentrationEnable.isChecked():
1523                                        self.progressBarHelicopterConcentration.setValue(packet['eSense']['attention'])
1524                                if self.pushButtonWheelchairConcentrationEnable.isChecked():
1525                                        self.progressBarWheelchairConcentration.setValue(packet['eSense']['attention'])
1526                       
1527                        if ('meditation' in packet['eSense'].keys()):
1528                                if self.pushButtonRelaxationEnable.isChecked():
1529                                        self.progressBarRelaxation.setValue(packet['eSense']['meditation'])
1530                                if self.pushButtonHelicopterRelaxationEnable.isChecked():
1531                                        self.progressBarHelicopterRelaxation.setValue(packet['eSense']['meditation'])
1532                                if self.pushButtonWheelchairRelaxationEnable.isChecked():
1533                                        self.progressBarWheelchairRelaxation.setValue(packet['eSense']['meditation'])
1534               
1535               
1536                self.updateNXTSpeed()
1537                self.updateHelicopterSpeed()
1538                self.updateWheelchairSpeed()
1539       
1540       
1541        ##################################################################
1542
1543        def sendFeedback(self):
1544               
1545                values = {}
1546
1547                values['name'] = str(self.lineEditFeedbackName.text())
1548                values['email'] = str(self.lineEditFeedbackEmail.text())
1549                values['comment'] = str(self.textEditFeedback.toPlainText())
1550               
1551                values['subject'] = '[brainstorms feedback]'
1552                values['capcha_contact'] = 'brainstorms'
1553               
1554               
1555                url_data = urllib.urlencode(values)
1556               
1557                try:
1558                        page = urllib.urlopen(BRAINSTORMS_FEEDBACK_URL, url_data)
1559                       
1560                        reply = QtGui.QMessageBox.information( \
1561                              self, \
1562                              'Feedback Sent', \
1563                              'Thank you for your feedback', \
1564                              'OK')
1565                       
1566                        self.lineEditFeedbackName.setText('')
1567                        self.lineEditFeedbackEmail.setText('')
1568                        self.textEditFeedback.setText('')
1569               
1570                except:
1571                        reply = QtGui.QMessageBox.information( \
1572                              self, \
1573                              'Feedback Sent', \
1574                              'We\'re sorry but there was an error submitting your feedback.\nPlease email contact@puzzlebox.info instead.', \
1575                              'OK')
1576       
1577       
1578        ##################################################################
1579       
1580        def closeEvent(self, event):
1581               
1582                quit_message = "Are you sure you want to exit the program?"
1583               
1584                reply = QtGui.QMessageBox.question( \
1585                           self, \
1586                          'Quit Puzzlebox Brainstorms', \
1587                           quit_message, \
1588                           QtGui.QMessageBox.Yes, \
1589                           QtGui.QMessageBox.No)
1590               
1591                if reply == QtGui.QMessageBox.Yes:
1592                       
1593                        if self.brainstormsClient != None:
1594                                self.stopMotors()
1595                                self.brainstormsClient.socket.flush()
1596                               
1597                                if self.brainstormsServer != None:
1598                                       
1599                                        if self.brainstormsServer.rc == None:
1600                                               
1601                                                bluetooth_device = str(self.comboBoxNXTPortSelect.currentText())
1602                                                self.brainstormsServer.executeCommand( \
1603                                                        'stop_motors', \
1604                                                        bluetooth_device=bluetooth_device)
1605                                               
1606                                        else:
1607                                                self.brainstormsServer.rc.run('stop_motors')
1608                       
1609                       
1610                        event.accept()
1611               
1612                else:
1613                        event.ignore()
1614
1615
1616#####################################################################
1617# Functions
1618#####################################################################
1619
1620#####################################################################
1621# Main
1622#####################################################################
1623
1624if __name__ == '__main__':
1625       
1626        #log = puzzlebox_logger.puzzlebox_logger(logfile='client_interface')
1627        log = None
1628       
1629        app = QtGui.QApplication(sys.argv)
1630       
1631        window = puzzlebox_brainstorms_client_interface(log, DEBUG)
1632        window.show()
1633       
1634        sys.exit(app.exec_())
1635
Note: See TracBrowser for help on using the repository browser.