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

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

Brainstorms/Helicopter_Control.py:

  • DEVICE_BUFFER_TIMER set to 21ms

Brainstorms/Interface?.py:

  • hover and fly_forward working
File size: 48.7 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=2)
425                      #DEBUG=self.DEBUG)
426               
427                self.helicopter.start()
428               
429                self.disconnect(self.pushButtonHelicopterConnect, \
430                                  QtCore.SIGNAL("clicked()"), \
431                                  self.connectToRCHelicopter)
432               
433                self.connect(self.pushButtonHelicopterConnect, \
434                                  QtCore.SIGNAL("clicked()"), \
435                                  self.disconnectFromRCHelicopter)
436               
437                self.pushButtonHelicopterConnect.setText('Disconnect')
438               
439                self.comboBoxHelicopterTransmitter.setEnabled(False)
440                self.comboBoxHelicopterPortSelect.setEnabled(False)
441                self.pushButtonHelicopterSearch.setEnabled(False)
442               
443                self.pushButtonHelicopterHover.setEnabled(True)
444                self.pushButtonHelicopterFlyForward.setEnabled(True)
445                self.pushButtonHelicopterLand.setEnabled(True)
446                self.pushButtonHelicopterThrottle.setEnabled(True)
447                self.verticalSliderHelicopterThrottle.setEnabled(True)
448                self.pushButtonHelicopterElevatorForward.setEnabled(True)
449                self.verticalSliderHelicopterElevatorForward.setEnabled(True)
450                self.pushButtonHelicopterElevatorReverse.setEnabled(True)
451                self.verticalSliderHelicopterElevatorReverse.setEnabled(True)
452                self.pushButtonHelicopterRudderLeft.setEnabled(True)
453                self.horizontalSliderHelicopterRudderLeft.setEnabled(True)
454                self.pushButtonHelicopterRudderRight.setEnabled(True)
455                self.horizontalSliderHelicopterRudderRight.setEnabled(True)
456                self.pushButtonHelicopterAileronLeft.setEnabled(True)
457                self.horizontalSliderHelicopterAileronLeft.setEnabled(True)
458                self.pushButtonHelicopterAileronRight.setEnabled(True)
459                self.horizontalSliderHelicopterAileronRight.setEnabled(True)
460       
461       
462        ##################################################################
463       
464        def disconnectFromRCHelicopter(self):
465               
466                #self.helicopter.command = 'neutral'
467                #self.helicopter.processCommand()
468                self.helicopter.neutral()
469               
470                self.helicopter.stop()
471               
472                self.disconnect(self.pushButtonHelicopterConnect, \
473                                  QtCore.SIGNAL("clicked()"), \
474                                  self.disconnectFromRCHelicopter)
475               
476                self.connect(self.pushButtonHelicopterConnect, \
477                                  QtCore.SIGNAL("clicked()"), \
478                                  self.connectToRCHelicopter)
479               
480                self.pushButtonHelicopterConnect.setText('Connect')
481               
482                self.comboBoxHelicopterTransmitter.setEnabled(True)
483                self.comboBoxHelicopterPortSelect.setEnabled(True)
484                self.pushButtonHelicopterSearch.setEnabled(True)
485               
486                self.pushButtonHelicopterHover.setEnabled(False)
487                self.pushButtonHelicopterFlyForward.setEnabled(False)
488                self.pushButtonHelicopterLand.setEnabled(False)
489                self.pushButtonHelicopterThrottle.setEnabled(False)
490                self.verticalSliderHelicopterThrottle.setEnabled(False)
491                self.pushButtonHelicopterElevatorForward.setEnabled(False)
492                self.verticalSliderHelicopterElevatorForward.setEnabled(False)
493                self.pushButtonHelicopterElevatorReverse.setEnabled(False)
494                self.verticalSliderHelicopterElevatorReverse.setEnabled(False)
495                self.pushButtonHelicopterRudderLeft.setEnabled(False)
496                self.horizontalSliderHelicopterRudderLeft.setEnabled(False)
497                self.pushButtonHelicopterRudderRight.setEnabled(False)
498                self.horizontalSliderHelicopterRudderRight.setEnabled(False)
499                self.pushButtonHelicopterAileronLeft.setEnabled(False)
500                self.horizontalSliderHelicopterAileronLeft.setEnabled(False)
501                self.pushButtonHelicopterAileronRight.setEnabled(False)
502                self.horizontalSliderHelicopterAileronRight.setEnabled(False)
503       
504       
505        ##################################################################
506       
507        def connectToWheelchair(self):
508               
509                self.disconnect(self.pushButtonWheelchairConnect, \
510                                  QtCore.SIGNAL("clicked()"), \
511                                  self.connectToWheelchair)
512               
513                self.connect(self.pushButtonWheelchairConnect, \
514                                  QtCore.SIGNAL("clicked()"), \
515                                  self.disconnectFromWheelchair)
516               
517                self.pushButtonWheelchairConnect.setText('Disconnect')
518               
519                self.comboBoxWheelchairTransmitter.setEnabled(False)
520                self.comboBoxWheelchairPortSelect.setEnabled(False)
521                self.pushButtonWheelchairSearch.setEnabled(False)
522               
523                self.pushButtonWheelchairForward.setEnabled(True)
524                self.pushButtonWheelchairReverse.setEnabled(True)
525                self.pushButtonWheelchairLeft.setEnabled(True)
526                self.pushButtonWheelchairRight.setEnabled(True)
527                self.pushButtonWheelchairStop.setEnabled(True)
528                self.dialWheelchairSpeed.setEnabled(True)
529       
530       
531        ##################################################################
532       
533        def disconnectFromWheelchair(self):
534               
535                self.disconnect(self.pushButtonWheelchairConnect, \
536                                  QtCore.SIGNAL("clicked()"), \
537                                  self.disconnectFromWheelchair)
538               
539                self.connect(self.pushButtonWheelchairConnect, \
540                                  QtCore.SIGNAL("clicked()"), \
541                                  self.connectToWheelchair)
542               
543                self.pushButtonWheelchairConnect.setText('Connect')
544               
545                self.comboBoxWheelchairTransmitter.setEnabled(True)
546                self.comboBoxWheelchairPortSelect.setEnabled(True)
547                self.pushButtonWheelchairSearch.setEnabled(True)
548               
549                self.pushButtonWheelchairForward.setEnabled(False)
550                self.pushButtonWheelchairReverse.setEnabled(False)
551                self.pushButtonWheelchairLeft.setEnabled(False)
552                self.pushButtonWheelchairRight.setEnabled(False)
553                self.pushButtonWheelchairStop.setEnabled(False)
554                self.dialWheelchairSpeed.setEnabled(False)
555       
556       
557        ##################################################################
558       
559        def updateConcentrationButton(self):
560               
561                if self.pushButtonConcentrationEnable.isChecked():
562                       
563                        self.pushButtonConcentrationEnable.setText('Enabled')
564               
565                else:
566                       
567                        self.pushButtonConcentrationEnable.setText('Disabled')
568                        self.progressBarConcentration.setValue(0)
569               
570               
571                self.updateSpeed()
572       
573       
574        ##################################################################
575       
576        def updateRelaxationButton(self):
577               
578                if self.pushButtonRelaxationEnable.isChecked():
579               
580                        self.pushButtonRelaxationEnable.setText('Enabled')
581               
582                else:
583                       
584                        self.pushButtonRelaxationEnable.setText('Disabled')
585                        self.progressBarRelaxation.setValue(0)
586               
587               
588                self.updateNXTSpeed()
589       
590       
591        ##################################################################
592       
593        def updateSpeedButton(self):
594               
595                if self.pushButtonSpeedEnable.isChecked():
596               
597                        self.pushButtonSpeedEnable.setText('Enabled')
598                        self.updateSpeed()
599               
600                else:
601                       
602                        self.pushButtonSpeedEnable.setText('Disabled')
603                        self.progressBarSpeed.setValue(0)
604                        self.stopMotors()
605       
606       
607        ##################################################################
608       
609        def updateHelicopterConcentrationButton(self):
610               
611                if self.pushButtonHelicopterConcentrationEnable.isChecked():
612                       
613                        self.pushButtonHelicopterConcentrationEnable.setText('Enabled')
614               
615                else:
616                       
617                        self.pushButtonHelicopterConcentrationEnable.setText('Disabled')
618                        self.progressBarHelicopterConcentration.setValue(0)
619               
620               
621                self.updateHelicopterSpeed()
622       
623       
624        ##################################################################
625       
626        def updateHelicopterRelaxationButton(self):
627               
628                if self.pushButtonHelicopterRelaxationEnable.isChecked():
629               
630                        self.pushButtonHelicopterRelaxationEnable.setText('Enabled')
631               
632                else:
633                       
634                        self.pushButtonHelicopterRelaxationEnable.setText('Disabled')
635                        self.progressBarHelicopterRelaxation.setValue(0)
636               
637               
638                self.updateHelicopterSpeed()
639       
640       
641        ##################################################################
642       
643        def updateHelicopterSpeedButton(self):
644               
645                if self.pushButtonHelicopterSpeedEnable.isChecked():
646               
647                        self.pushButtonHelicopterSpeedEnable.setText('Enabled')
648                        self.updateHelicopterSpeed()
649               
650                else:
651                       
652                        self.pushButtonHelicopterSpeedEnable.setText('Disabled')
653                        self.progressBarHelicopterSpeed.setValue(0)
654                        self.stopMotors()
655       
656       
657        ##################################################################
658       
659        def updateWheelchairConcentrationButton(self):
660               
661                if self.pushButtonWheelchairConcentrationEnable.isChecked():
662                       
663                        self.pushButtonWheelchairConcentrationEnable.setText('Enabled')
664               
665                else:
666                       
667                        self.pushButtonWheelchairConcentrationEnable.setText('Disabled')
668                        self.progressBarWheelchairConcentration.setValue(0)
669               
670               
671                self.updateWheelchairSpeed()
672       
673       
674        ##################################################################
675       
676        def updateWheelchairRelaxationButton(self):
677               
678                if self.pushButtonWheelchairRelaxationEnable.isChecked():
679               
680                        self.pushButtonWheelchairRelaxationEnable.setText('Enabled')
681               
682                else:
683                       
684                        self.pushButtonWheelchairRelaxationEnable.setText('Disabled')
685                        self.progressBarWheelchairRelaxation.setValue(0)
686               
687               
688                self.updateWheelchairSpeed()
689       
690       
691        ##################################################################
692       
693        def updateWheelchairSpeedButton(self):
694               
695                if self.pushButtonWheelchairSpeedEnable.isChecked():
696               
697                        self.pushButtonWheelchairSpeedEnable.setText('Enabled')
698                        self.updateWheelchairSpeed()
699               
700                else:
701                       
702                        self.pushButtonWheelchairSpeedEnable.setText('Disabled')
703                        self.progressBarWheelchairSpeed.setValue(0)
704                        self.stopMotors()
705       
706       
707        ##################################################################
708       
709        def connectWidgets(self):
710               
711                # LEGO Mindstorms Buttons
712                self.connect(self.pushButtonTurnLeft, QtCore.SIGNAL("pressed()"), \
713                             self.turnLeft)
714                self.connect(self.pushButtonTurnLeft, QtCore.SIGNAL("released()"), \
715                             self.stopMotors)
716               
717                self.connect(self.pushButtonForward, QtCore.SIGNAL("pressed()"), \
718                             self.driveForward)
719                self.connect(self.pushButtonForward, QtCore.SIGNAL("released()"), \
720                             self.stopMotors)
721               
722                self.connect(self.pushButtonTurnRight, QtCore.SIGNAL("pressed()"), \
723                             self.turnRight)
724                self.connect(self.pushButtonTurnRight, QtCore.SIGNAL("released()"), \
725                             self.stopMotors)
726               
727                self.connect(self.pushButtonTurnLeftReverse, QtCore.SIGNAL("pressed()"), \
728                             self.turnLeftInReverse)
729                self.connect(self.pushButtonTurnLeftReverse, QtCore.SIGNAL("released()"), \
730                             self.stopMotors)
731               
732                self.connect(self.pushButtonReverse, QtCore.SIGNAL("pressed()"), \
733                             self.driveReverse)
734                self.connect(self.pushButtonReverse, QtCore.SIGNAL("released()"), \
735                             self.stopMotors)
736               
737                self.connect(self.pushButtonTurnRightReverse, QtCore.SIGNAL("pressed()"), \
738                             self.turnRightInReverse)
739                self.connect(self.pushButtonTurnRightReverse, QtCore.SIGNAL("released()"), \
740                             self.stopMotors)
741               
742               
743                self.connect(self.pushButtonNXTSearch, \
744                                  QtCore.SIGNAL("clicked()"), \
745                                  self.searchForDevices)
746               
747                self.connect(self.pushButtonNXTConnect, \
748                                  QtCore.SIGNAL("clicked()"), \
749                                  self.connectToBrainstormsServer)
750               
751               
752                self.connect(self.pushButtonConcentrationEnable, \
753                                  QtCore.SIGNAL("clicked()"), \
754                                  self.updateConcentrationButton)
755               
756                self.connect(self.pushButtonRelaxationEnable, \
757                                  QtCore.SIGNAL("clicked()"), \
758                                  self.updateRelaxationButton)
759               
760                self.connect(self.pushButtonSpeedEnable, \
761                                  QtCore.SIGNAL("clicked()"), \
762                                  self.updateSpeedButton)
763               
764               
765                self.connect(self.pushButtonNXTMessageOne, QtCore.SIGNAL("pressed()"), \
766                             self.sendMessageOne)
767               
768                self.connect(self.pushButtonNXTMessageTwo, QtCore.SIGNAL("pressed()"), \
769                             self.sendMessageTwo)
770               
771                self.connect(self.pushButtonNXTMessageThree, QtCore.SIGNAL("pressed()"), \
772                             self.sendMessageThree)
773               
774                self.connect(self.pushButtonNXTMessageFour, QtCore.SIGNAL("pressed()"), \
775                             self.sendMessageFour)
776               
777                self.connect(self.pushButtonNXTMessageFive, QtCore.SIGNAL("pressed()"), \
778                             self.sendMessageFive)
779               
780                self.connect(self.pushButtonNXTMessageSix, QtCore.SIGNAL("pressed()"), \
781                             self.sendMessageSix)
782               
783               
784               
785                # RC Helicopter Buttons
786                self.connect(self.pushButtonHelicopterSearch, \
787                                  QtCore.SIGNAL("clicked()"), \
788                                  self.searchForDevices)
789               
790                self.connect(self.pushButtonHelicopterConnect, \
791                                  QtCore.SIGNAL("clicked()"), \
792                                  self.connectToRCHelicopter)
793               
794               
795                self.connect(self.pushButtonHelicopterConcentrationEnable, \
796                                  QtCore.SIGNAL("clicked()"), \
797                                  self.updateHelicopterConcentrationButton)
798               
799                self.connect(self.pushButtonHelicopterRelaxationEnable, \
800                                  QtCore.SIGNAL("clicked()"), \
801                                  self.updateHelicopterRelaxationButton)
802               
803                self.connect(self.pushButtonHelicopterSpeedEnable, \
804                                  QtCore.SIGNAL("clicked()"), \
805                                  self.updateHelicopterSpeedButton)
806               
807               
808                self.connect(self.pushButtonHelicopterHover, \
809                                  QtCore.SIGNAL("clicked()"), \
810                                  self.enableHelicopterHover)
811               
812                self.connect(self.pushButtonHelicopterFlyForward, \
813                                  QtCore.SIGNAL("clicked()"), \
814                                  self.enableHelicopterFlyForward)
815               
816                self.connect(self.pushButtonHelicopterLand, \
817                                  QtCore.SIGNAL("clicked()"), \
818                                  self.landHelicopter)
819               
820               
821               
822                # Wheelchair Buttons
823                self.connect(self.pushButtonWheelchairSearch, \
824                                  QtCore.SIGNAL("clicked()"), \
825                                  self.searchForDevices)
826               
827                self.connect(self.pushButtonWheelchairConnect, \
828                                  QtCore.SIGNAL("clicked()"), \
829                                  self.connectToWheelchair)
830               
831               
832                self.connect(self.pushButtonWheelchairConcentrationEnable, \
833                                  QtCore.SIGNAL("clicked()"), \
834                                  self.updateWheelchairConcentrationButton)
835               
836                self.connect(self.pushButtonWheelchairRelaxationEnable, \
837                                  QtCore.SIGNAL("clicked()"), \
838                                  self.updateWheelchairRelaxationButton)
839               
840                self.connect(self.pushButtonWheelchairSpeedEnable, \
841                                  QtCore.SIGNAL("clicked()"), \
842                                  self.updateWheelchairSpeedButton)
843               
844               
845                self.connect(self.pushButtonWheelchairForward, \
846                                  QtCore.SIGNAL("clicked()"), \
847                                  self.driveWheelchairForward)
848               
849                self.connect(self.pushButtonWheelchairReverse, \
850                                  QtCore.SIGNAL("clicked()"), \
851                                  self.driveWheelchairReverse)
852               
853                self.connect(self.pushButtonWheelchairLeft, \
854                                  QtCore.SIGNAL("clicked()"), \
855                                  self.driveWheelchairLeft)
856               
857                self.connect(self.pushButtonWheelchairRight, \
858                                  QtCore.SIGNAL("clicked()"), \
859                                  self.driveWheelchairRight)
860               
861                self.connect(self.pushButtonWheelchairStop, \
862                                  QtCore.SIGNAL("clicked()"), \
863                                  self.stopWheelchair)
864               
865               
866               
867                # Control Panel Buttons
868                self.connect(self.pushButtonMessageOne, QtCore.SIGNAL("pressed()"), \
869                             self.sendMessageOne)
870               
871                self.connect(self.pushButtonMessageTwo, QtCore.SIGNAL("pressed()"), \
872                             self.sendMessageTwo)
873               
874                self.connect(self.pushButtonMessageThree, QtCore.SIGNAL("pressed()"), \
875                             self.sendMessageThree)
876               
877                self.connect(self.pushButtonMessageFour, QtCore.SIGNAL("pressed()"), \
878                             self.sendMessageFour)
879               
880                self.connect(self.pushButtonMessageFive, QtCore.SIGNAL("pressed()"), \
881                             self.sendMessageFive)
882               
883                self.connect(self.pushButtonMessageSix, QtCore.SIGNAL("pressed()"), \
884                             self.sendMessageSix)
885               
886               
887                self.connect(self.pushButtonThinkGearConnect, \
888                                  QtCore.SIGNAL("clicked()"), \
889                                  self.connectToThinkGearHost)
890               
891                self.connect(self.pushButtonSendFeedback, \
892                                  QtCore.SIGNAL("clicked()"), \
893                                  self.sendFeedback)
894               
895               
896                #shortcut = QtGui.QShortcut(self)
897                #shortcut.setKey(tr("Down"))
898                #self.connect(shortcut, QtCore.SIGNAL("pressed()"), self.driveReverse)
899               
900               
901                action = QtGui.QAction(self)
902                action.setShortcut(QtGui.QKeySequence("W"))
903                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonForward, QtCore.SLOT("animateClick()"))
904                self.addAction(action)
905               
906                action = QtGui.QAction(self)
907                action.setShortcut(QtGui.QKeySequence("Up"))
908                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonForward, QtCore.SLOT("animateClick()"))
909                self.addAction(action)
910               
911               
912                action = QtGui.QAction(self)
913                action.setShortcut(QtGui.QKeySequence("Left"))
914                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnLeft, QtCore.SLOT("animateClick()"))
915                self.addAction(action)
916               
917                action = QtGui.QAction(self)
918                action.setShortcut(QtGui.QKeySequence("A"))
919                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnLeft, QtCore.SLOT("animateClick()"))
920                self.addAction(action)
921               
922               
923                action = QtGui.QAction(self)
924                action.setShortcut(QtGui.QKeySequence("S"))
925                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonReverse, QtCore.SLOT("animateClick()"))
926                self.addAction(action)
927               
928                action = QtGui.QAction(self)
929                action.setShortcut(QtGui.QKeySequence("Down"))
930                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonReverse, QtCore.SLOT("animateClick()"))
931                self.addAction(action)
932               
933               
934                action = QtGui.QAction(self)
935                action.setShortcut(QtGui.QKeySequence("D"))
936                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnRight, QtCore.SLOT("animateClick()"))
937                self.addAction(action)
938               
939                action = QtGui.QAction(self)
940                action.setShortcut(QtGui.QKeySequence("Right"))
941                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnRight, QtCore.SLOT("animateClick()"))
942                self.addAction(action)
943               
944               
945                action = QtGui.QAction(self)
946                action.setShortcut(QtGui.QKeySequence("Z"))
947                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnLeftReverse, QtCore.SLOT("animateClick()"))
948                self.addAction(action)
949               
950               
951                action = QtGui.QAction(self)
952                action.setShortcut(QtGui.QKeySequence("C"))
953                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonTurnRightReverse, QtCore.SLOT("animateClick()"))
954                self.addAction(action)
955               
956               
957               
958                # RC Helicopter Buttons
959               
960                action = QtGui.QAction(self)
961                action.setShortcut(QtGui.QKeySequence("Home"))
962                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonHelicopterHover, QtCore.SLOT("animateClick()"))
963                self.addAction(action)
964               
965                action = QtGui.QAction(self)
966                action.setShortcut(QtGui.QKeySequence("PgUp"))
967                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonHelicopterFlyForward, QtCore.SLOT("animateClick()"))
968                self.addAction(action)
969               
970                action = QtGui.QAction(self)
971                action.setShortcut(QtGui.QKeySequence("End"))
972                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonHelicopterLand, QtCore.SLOT("animateClick()"))
973                self.addAction(action)
974               
975               
976               
977                # Wheelchair Buttons
978               
979                action = QtGui.QAction(self)
980                action.setShortcut(QtGui.QKeySequence("i"))
981                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairForward, QtCore.SLOT("animateClick()"))
982                self.addAction(action)
983               
984                action = QtGui.QAction(self)
985                action.setShortcut(QtGui.QKeySequence("k"))
986                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairReverse, QtCore.SLOT("animateClick()"))
987                self.addAction(action)
988               
989                action = QtGui.QAction(self)
990                action.setShortcut(QtGui.QKeySequence("j"))
991                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairLeft, QtCore.SLOT("animateClick()"))
992                self.addAction(action)
993               
994                action = QtGui.QAction(self)
995                action.setShortcut(QtGui.QKeySequence("l"))
996                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairRight, QtCore.SLOT("animateClick()"))
997                self.addAction(action)
998               
999                action = QtGui.QAction(self)
1000                action.setShortcut(QtGui.QKeySequence("Space"))
1001                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonWheelchairStop, QtCore.SLOT("animateClick()"))
1002                self.addAction(action)
1003               
1004               
1005               
1006                # Control Panel Buttons
1007               
1008                action = QtGui.QAction(self)
1009                action.setShortcut(QtGui.QKeySequence("1"))
1010                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageOne, QtCore.SLOT("animateClick()"))
1011                self.addAction(action)
1012               
1013                action = QtGui.QAction(self)
1014                action.setShortcut(QtGui.QKeySequence("2"))
1015                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageTwo, QtCore.SLOT("animateClick()"))
1016                self.addAction(action)
1017               
1018                action = QtGui.QAction(self)
1019                action.setShortcut(QtGui.QKeySequence("3"))
1020                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageThree, QtCore.SLOT("animateClick()"))
1021                self.addAction(action)
1022               
1023                action = QtGui.QAction(self)
1024                action.setShortcut(QtGui.QKeySequence("4"))
1025                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageFour, QtCore.SLOT("animateClick()"))
1026                self.addAction(action)
1027               
1028                action = QtGui.QAction(self)
1029                action.setShortcut(QtGui.QKeySequence("5"))
1030                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageFive, QtCore.SLOT("animateClick()"))
1031                self.addAction(action)
1032               
1033                action = QtGui.QAction(self)
1034                action.setShortcut(QtGui.QKeySequence("6"))
1035                self.connect(action, QtCore.SIGNAL("activated()"), self.pushButtonNXTMessageSix, QtCore.SLOT("animateClick()"))
1036                self.addAction(action)
1037               
1038               
1039                #self.pushButtonForward.setAutoRepeat(False)
1040                #self.pushButtonForward.setAutoRepeatDelay(0)
1041                #self.pushButtonForward.setAutoRepeatInterval(0)
1042       
1043       
1044        ##################################################################
1045       
1046        def searchForDevices(self):
1047               
1048                nxt_devices = []
1049                rc_helicopter_devices = []
1050                wheelchair_devices = []
1051               
1052                #if (sys.platform != 'win32'):
1053                if False: # temporarily disabled
1054                       
1055                        # Bluetooth module doesn't compile properly under Windows
1056                       
1057                        bluetooth_devices = []
1058                       
1059                        try:
1060                                bluetooth_devices = bluetooth.discover_devices( \
1061                                                       duration=5, \
1062                                                       flush_cache=True, \
1063                                                       lookup_names=False)
1064                        except:
1065                                #command = '%s con' % PATH_TO_HCITOOL
1066                                command = '%s scan' % PATH_TO_HCITOOL
1067                               
1068                                output = os.popen(command, 'r')
1069                               
1070                                for line in output.readlines():
1071                                        print line
1072                                        try:
1073                                                address = line.split(' ')[2]
1074                                        except:
1075                                                pass
1076                                        else:
1077                                                bluetooth_devices.append(address)
1078                       
1079                        for address in bluetooth_devices:
1080                                device_name = bluetooth.lookup_name(address)
1081                                if ((device_name == 'NXT') and \
1082                                    (address not in nxt_devices)):
1083                                        nxt_devices.append(address)
1084                       
1085                       
1086                        if self.DEBUG:
1087                                print "Bluetooth NXT devices found:",
1088                                print nxt_devices
1089               
1090               
1091                # List all serial devices
1092                serial_devices = self.enumerateSerialPorts()
1093               
1094                for serial_device in serial_devices:
1095                        #serial_device = self.fullPortName(serial_device)
1096                        nxt_devices.append(serial_device)
1097                        rc_helicopter_devices.append(serial_device)
1098                        wheelchair_devices.append(serial_device)
1099               
1100               
1101                # Configure combo boxes
1102                if nxt_devices == []:
1103                        nxt_devices.append('N/A')
1104               
1105                if rc_helicopter_devices == []:
1106                        rc_helicopter_devices.append('N/A')
1107               
1108                if wheelchair_devices == []:
1109                        wheelchair_devices.append('N/A')
1110               
1111               
1112                # Don't reset combo boxes if already connected
1113                if self.pushButtonNXTConnect.text != 'Disconnect':
1114                       
1115                        self.comboBoxNXTPortSelect.clear()
1116                       
1117                        #nxt_devices.reverse()
1118                        for nxt_device in nxt_devices:
1119                                self.comboBoxNXTPortSelect.addItem(nxt_device)
1120               
1121               
1122                if self.pushButtonHelicopterConnect.text != 'Disconnect':
1123                       
1124                        self.comboBoxHelicopterPortSelect.clear()
1125                       
1126                        #rc_helicopter_devices.reverse()
1127                        for rc_helicopter in rc_helicopter_devices:
1128                                self.comboBoxHelicopterPortSelect.addItem(rc_helicopter)
1129       
1130       
1131                if self.pushButtonWheelchairConnect.text != 'Disconnect':
1132                       
1133                        self.comboBoxWheelchairPortSelect.clear()
1134                       
1135                        #rc_helicopter_devices.reverse()
1136                        for wheelchair in wheelchair_devices:
1137                                self.comboBoxWheelchairPortSelect.addItem(wheelchair)
1138       
1139       
1140        ##################################################################
1141       
1142        def enumerateSerialPorts(self):
1143               
1144                """ Uses the Win32 registry to return an
1145                iterator of serial (COM) ports
1146                existing on this computer.
1147               
1148                from http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/
1149                """
1150               
1151                serial_ports = []
1152               
1153                if (sys.platform == 'win32'):
1154                       
1155                        path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
1156                        try:
1157                                key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path)
1158                        except WindowsError:
1159                                #raise IterationError
1160                                #return
1161                                pass
1162                       
1163                        for i in itertools.count():
1164                                try:
1165                                        val = winreg.EnumValue(key, i)
1166                                        #yield str(val[1])
1167                                        serial_ports.append( str(val[1]) )
1168                                except EnvironmentError:
1169                                        break
1170               
1171               
1172                else:
1173                       
1174                        if os.path.exists(DEVICE_PATH):
1175                                device_list = os.listdir(DEVICE_PATH)
1176                               
1177                                device_list.sort()
1178                       
1179                                for device in device_list:
1180                                        if device.startswith('ttyUSB'):
1181                                                serial_ports.append( DEVICE_PATH + '/' + device )
1182                                for device in device_list:
1183                                        if device.startswith('rfcomm'):
1184                                                serial_ports.append( DEVICE_PATH + '/' + device )
1185                                for device in device_list:
1186                                        if device.startswith('ttyACM'):
1187                                                serial_ports.append( DEVICE_PATH + '/' + device )
1188                                for device in device_list:
1189                                        if device.startswith('ttyS'):
1190                                                serial_ports.append( DEVICE_PATH + '/' + device )
1191               
1192               
1193                return(serial_ports)
1194       
1195       
1196        ##################################################################
1197       
1198        def fullPortName(self, portname):
1199               
1200                """ Given a port-name (of the form COM7,
1201                COM12, CNCA0, etc.) returns a full
1202                name suitable for opening with the
1203                Serial class.
1204                """
1205               
1206                m = re.match('^COM(\d+)$', portname)
1207                if m and int(m.group(1)) < 10:
1208                        return portname
1209               
1210                return '\\\\.\\' + portname
1211       
1212       
1213        ##################################################################
1214       
1215        # LEGO Mindstorms Controls
1216       
1217        def turnLeft(self):
1218                self.brainstormsClient.sendCommand('turn_left')
1219                self.drive_state = 'turn_left'
1220       
1221        def driveForward(self):
1222                #if self.DEBUG:
1223                        #print "driveForward"
1224                self.pushButtonForward.setDown(True)
1225                if (self.drive_state != 'drive_forward'):
1226                        self.updateNXTSpeed(new_speed=DEFAULT_NXT_POWER_LEVEL)
1227                self.brainstormsClient.sendCommand('drive_forward', power=self.current_speed)
1228                self.drive_state = 'drive_forward'
1229       
1230        def turnRight(self):
1231                self.brainstormsClient.sendCommand('turn_right')
1232                self.drive_state = 'turn_right'
1233       
1234        def turnLeftInReverse(self):
1235                self.brainstormsClient.sendCommand('turn_left_in_reverse')
1236                self.drive_state = 'turn_left_in_reverse'
1237       
1238        def driveReverse(self):
1239                self.brainstormsClient.sendCommand('drive_reverse')
1240                self.drive_state = 'drive_reverse'
1241       
1242        def turnRightInReverse(self):
1243                self.brainstormsClient.sendCommand('turn_right_in_reverse')
1244                self.drive_state = 'turn_right_in_reverse'
1245       
1246        def stopMotors(self):
1247                self.pushButtonForward.setDown(False)
1248                if (self.current_speed != 0):
1249                        self.updateNXTSpeed(new_speed=0)
1250                if self.brainstormsClient != None:
1251                        self.brainstormsClient.sendCommand('stop_motors')
1252                self.drive_state = 'stop_motors'
1253       
1254        def sendMessageOne(self):
1255                message = str(self.lineEditMessageOne.text())
1256                self.brainstormsClient.sendCommand('send_message_1')
1257       
1258        def sendMessageTwo(self):
1259                message = str(self.lineEditMessageTwo.text())
1260                self.brainstormsClient.sendCommand('send_message_2')
1261       
1262        def sendMessageThree(self):
1263                message = str(self.lineEditMessageThree.text())
1264                self.brainstormsClient.sendCommand('send_message_3')
1265       
1266        def sendMessageFour(self):
1267                message = str(self.lineEditMessageFour.text())
1268                self.brainstormsClient.sendCommand('send_message_4')
1269       
1270        def sendMessageFive(self):
1271                message = str(self.lineEditMessageFive.text())
1272                self.brainstormsClient.sendCommand('send_message_5')
1273       
1274        def sendMessageSix(self):
1275                message = str(self.lineEditMessageSix.text())
1276                self.brainstormsClient.sendCommand('send_message_6')
1277       
1278       
1279        ##################################################################
1280       
1281        def enableHelicopterHover(self):
1282               
1283                #self.helicopter.command = 'hover'
1284                #self.helicopter.processCommand()
1285                self.helicopter.hover()
1286               
1287                self.disconnect(self.pushButtonHelicopterHover, \
1288                                                        QtCore.SIGNAL("clicked()"), \
1289                                                        self.enableHelicopterHover)
1290               
1291                self.connect(self.pushButtonHelicopterHover, \
1292                                  QtCore.SIGNAL("clicked()"), \
1293                                  self.disableHelicopterHover)
1294               
1295                if self.pushButtonHelicopterFlyForward.isChecked():
1296                        self.pushButtonHelicopterFlyForward.toggle()
1297                        self.disableHelicopterFlyForward()
1298       
1299       
1300        ##################################################################
1301       
1302        def disableHelicopterHover(self):
1303               
1304                #self.helicopter.command = 'neutral'
1305                #self.helicopter.processCommand()
1306                self.helicopter.neutral()
1307               
1308                self.disconnect(self.pushButtonHelicopterHover, \
1309                                                        QtCore.SIGNAL("clicked()"), \
1310                                                        self.disableHelicopterHover)
1311               
1312                self.connect(self.pushButtonHelicopterHover, \
1313                                  QtCore.SIGNAL("clicked()"), \
1314                                  self.enableHelicopterHover)
1315       
1316       
1317        ##################################################################
1318       
1319        def enableHelicopterFlyForward(self):
1320               
1321                #self.helicopter.command = 'fly_forward'
1322                #self.helicopter.processCommand()
1323                self.helicopter.fly_forward()
1324               
1325                self.disconnect(self.pushButtonHelicopterFlyForward, \
1326                                                        QtCore.SIGNAL("clicked()"), \
1327                                                        self.enableHelicopterFlyForward)
1328               
1329                self.connect(self.pushButtonHelicopterFlyForward, \
1330                                  QtCore.SIGNAL("clicked()"), \
1331                                  self.disableHelicopterFlyForward)
1332               
1333                if self.pushButtonHelicopterHover.isChecked():
1334                        self.pushButtonHelicopterHover.toggle()
1335                        self.disableHelicopterHover()
1336       
1337       
1338        ##################################################################
1339       
1340        def disableHelicopterFlyForward(self):
1341               
1342                #self.helicopter.command = 'neutral'
1343                #self.helicopter.processCommand()
1344                self.helicopter.neutral()
1345               
1346                self.disconnect(self.pushButtonHelicopterFlyForward, \
1347                                                        QtCore.SIGNAL("clicked()"), \
1348                                                        self.disableHelicopterFlyForward)
1349               
1350                self.connect(self.pushButtonHelicopterFlyForward, \
1351                                  QtCore.SIGNAL("clicked()"), \
1352                                  self.enableHelicopterFlyForward)
1353       
1354       
1355        ##################################################################
1356       
1357        def landHelicopter(self):
1358               
1359                #self.helicopter.command = 'neutral'
1360                #self.helicopter.processCommand()
1361                self.helicopter.neutral()
1362               
1363                if self.pushButtonHelicopterHover.isChecked():
1364                        self.pushButtonHelicopterHover.toggle()
1365                        self.disableHelicopterHover()
1366                if self.pushButtonHelicopterFlyForward.isChecked():
1367                        self.pushButtonHelicopterFlyForward.toggle()
1368                        self.disableHelicopterFlyForward()
1369       
1370       
1371        ##################################################################
1372       
1373        def driveWheelchairForward(self):
1374                print "WheelchairForward"
1375       
1376        def driveWheelchairReverse(self):
1377                print "WheelchairReverse"
1378       
1379        def driveWheelchairLeft(self):
1380                print "WheelchairLeft"
1381       
1382        def driveWheelchairRight(self):
1383                print "WheelchairRight"
1384       
1385        def stopWheelchair(self):
1386                print "stopWheelchair"
1387       
1388       
1389        ##################################################################
1390       
1391        def updateNXTSpeed(self, new_speed=None):
1392               
1393                if new_speed == None:
1394               
1395                        concentration=self.progressBarConcentration.value()
1396                        relaxation=self.progressBarRelaxation.value()
1397                       
1398                        new_speed = self.calculateSpeed(concentration, relaxation)
1399               
1400               
1401                # Update GUI
1402                if self.pushButtonSpeedEnable.isChecked():
1403                        self.progressBarSpeed.setValue(new_speed)
1404               
1405               
1406                # If there is a change between the new and current speeds
1407                # and either the robot is currently driving forward
1408                # or the "speed control" button is enabled,
1409                # then send the updated speed to the robot
1410                if ((self.current_speed != new_speed) and \
1411                         ((self.drive_state == 'drive_forward') or \
1412                          (self.pushButtonSpeedEnable.isChecked()))):
1413                       
1414                        if (new_speed == 0):
1415                                self.current_speed = new_speed
1416                                self.stopMotors()
1417                        else:
1418                                if ((self.brainstormsClient != None) and \
1419                                    (self.pushButtonSpeedEnable.isChecked())):
1420                                        self.pushButtonForward.setDown(True)
1421                                        self.brainstormsClient.sendCommand('drive_forward', power=new_speed)
1422               
1423               
1424                self.current_speed = new_speed
1425       
1426       
1427        ##################################################################
1428       
1429        def updateHelicopterSpeed(self, new_speed=None):
1430               
1431                if new_speed == None:
1432               
1433                        concentration=self.progressBarHelicopterConcentration.value()
1434                        relaxation=self.progressBarHelicopterRelaxation.value()
1435                       
1436                        new_speed = self.calculateSpeed(concentration, relaxation)
1437               
1438               
1439                # Update GUI
1440                if self.pushButtonHelicopterSpeedEnable.isChecked():
1441                        self.progressBarHelicopterSpeed.setValue(new_speed)
1442               
1443               
1444                self.current_speed = new_speed
1445       
1446       
1447        ##################################################################
1448       
1449        def updateWheelchairSpeed(self, new_speed=None):
1450               
1451                if new_speed == None:
1452               
1453                        concentration=self.progressBarWheelchairConcentration.value()
1454                        relaxation=self.progressBarWheelchairRelaxation.value()
1455                       
1456                        new_speed = self.calculateSpeed(concentration, relaxation)
1457               
1458               
1459                # Update GUI
1460                if self.pushButtonWheelchairSpeedEnable.isChecked():
1461                        self.progressBarWheelchairSpeed.setValue(new_speed)
1462               
1463               
1464                self.current_speed = new_speed
1465       
1466        ##################################################################
1467       
1468        def calculateSpeed(self, concentration, relaxation):
1469               
1470                speed = 0
1471               
1472                thresholds = THINKGEAR_POWER_THRESHOLDS
1473               
1474                match = int(concentration)
1475               
1476                while ((match not in thresholds['concentration'].keys()) and \
1477                            (match >= 0)):
1478                        match -= 1
1479               
1480               
1481                if match in thresholds['concentration'].keys():
1482                        speed = thresholds['concentration'][match]
1483               
1484               
1485                match = int(relaxation)
1486               
1487                while ((match not in thresholds['relaxation'].keys()) and \
1488                            (match >= 0)):
1489                        match -= 1
1490               
1491                if match in thresholds['relaxation'].keys():
1492                        speed = speed + thresholds['relaxation'][match]
1493               
1494               
1495                # LEGO Mindstorms power settings cannot exceed 100
1496                # and don't drive well with levels less than 50
1497                if (speed > 100):
1498                        speed = 100
1499                elif (speed < 50):
1500                        speed = 0
1501               
1502               
1503                return(speed)
1504       
1505       
1506        ##################################################################
1507       
1508        def processPacketThinkGear(self, packet):
1509               
1510                if ('eSense' in packet.keys()):
1511                       
1512                        if ('attention' in packet['eSense'].keys()):
1513                                if self.pushButtonConcentrationEnable.isChecked():
1514                                        self.progressBarConcentration.setValue(packet['eSense']['attention'])
1515                                if self.pushButtonHelicopterConcentrationEnable.isChecked():
1516                                        self.progressBarHelicopterConcentration.setValue(packet['eSense']['attention'])
1517                                if self.pushButtonWheelchairConcentrationEnable.isChecked():
1518                                        self.progressBarWheelchairConcentration.setValue(packet['eSense']['attention'])
1519                       
1520                        if ('meditation' in packet['eSense'].keys()):
1521                                if self.pushButtonRelaxationEnable.isChecked():
1522                                        self.progressBarRelaxation.setValue(packet['eSense']['meditation'])
1523                                if self.pushButtonHelicopterRelaxationEnable.isChecked():
1524                                        self.progressBarHelicopterRelaxation.setValue(packet['eSense']['meditation'])
1525                                if self.pushButtonWheelchairRelaxationEnable.isChecked():
1526                                        self.progressBarWheelchairRelaxation.setValue(packet['eSense']['meditation'])
1527               
1528               
1529                self.updateNXTSpeed()
1530                self.updateHelicopterSpeed()
1531                self.updateWheelchairSpeed()
1532       
1533       
1534        ##################################################################
1535
1536        def sendFeedback(self):
1537               
1538                values = {}
1539
1540                values['name'] = str(self.lineEditFeedbackName.text())
1541                values['email'] = str(self.lineEditFeedbackEmail.text())
1542                values['comment'] = str(self.textEditFeedback.toPlainText())
1543               
1544                values['subject'] = '[brainstorms feedback]'
1545                values['capcha_contact'] = 'brainstorms'
1546               
1547               
1548                url_data = urllib.urlencode(values)
1549               
1550                try:
1551                        page = urllib.urlopen(BRAINSTORMS_FEEDBACK_URL, url_data)
1552                       
1553                        reply = QtGui.QMessageBox.information( \
1554                              self, \
1555                              'Feedback Sent', \
1556                              'Thank you for your feedback', \
1557                              'OK')
1558                       
1559                        self.lineEditFeedbackName.setText('')
1560                        self.lineEditFeedbackEmail.setText('')
1561                        self.textEditFeedback.setText('')
1562               
1563                except:
1564                        reply = QtGui.QMessageBox.information( \
1565                              self, \
1566                              'Feedback Sent', \
1567                              'We\'re sorry but there was an error submitting your feedback.\nPlease email contact@puzzlebox.info instead.', \
1568                              'OK')
1569       
1570       
1571        ##################################################################
1572       
1573        def closeEvent(self, event):
1574               
1575                quit_message = "Are you sure you want to exit the program?"
1576               
1577                reply = QtGui.QMessageBox.question( \
1578                           self, \
1579                          'Quit Puzzlebox Brainstorms', \
1580                           quit_message, \
1581                           QtGui.QMessageBox.Yes, \
1582                           QtGui.QMessageBox.No)
1583               
1584                if reply == QtGui.QMessageBox.Yes:
1585                       
1586                        if self.brainstormsClient != None:
1587                                self.stopMotors()
1588                                self.brainstormsClient.socket.flush()
1589                               
1590                                if self.brainstormsServer != None:
1591                                       
1592                                        if self.brainstormsServer.rc == None:
1593                                               
1594                                                bluetooth_device = str(self.comboBoxNXTPortSelect.currentText())
1595                                                self.brainstormsServer.executeCommand( \
1596                                                        'stop_motors', \
1597                                                        bluetooth_device=bluetooth_device)
1598                                               
1599                                        else:
1600                                                self.brainstormsServer.rc.run('stop_motors')
1601                       
1602                       
1603                        event.accept()
1604               
1605                else:
1606                        event.ignore()
1607
1608
1609#####################################################################
1610# Functions
1611#####################################################################
1612
1613#####################################################################
1614# Main
1615#####################################################################
1616
1617if __name__ == '__main__':
1618       
1619        #log = puzzlebox_logger.puzzlebox_logger(logfile='client_interface')
1620        log = None
1621       
1622        app = QtGui.QApplication(sys.argv)
1623       
1624        window = puzzlebox_brainstorms_client_interface(log, DEBUG)
1625        window.show()
1626       
1627        sys.exit(app.exec_())
1628
Note: See TracBrowser for help on using the repository browser.