Ignore:
Timestamp:
06/27/10 05:26:28 (11 years ago)
Author:
sc
Message:

configuration:

  • power thresholds added for concentration and relaxation

client_interface_qt:

  • basic client networking added
  • signal connections added to widgets
  • configuration settings added for widgets

qt4_form:

  • LEGO Mindstorms NXT label added to Bluetooth section

client:

  • server_host and server_port read from defaults when not specified
File:
1 edited

Legend:

Unmodified
Added
Removed
  • remote_control/puzzlebox_brainstorms_client_interface_qt.py

    r65 r67  
    22# -*- coding: utf-8 -*- 
    33# 
    4 # Puzzlebox - Brainstorms - Client Interface 
     4# Puzzlebox - Brainstorms - Client Interface - Qt 
    55# 
    66# Copyright Puzzlebox Productions, LLC (2010) 
     
    99# For more information please refer to http://www.gnu.org/copyleft/gpl.html 
    1010# 
    11 # Last Update: 2010.06.10 
     11# Last Update: 2010.06.26 
    1212# 
    1313##################################################################### 
     
    1515import os, sys 
    1616 
    17 from PyQt4.QtCore import Qt, SIGNAL 
    18 from PyQt4.QtGui import * 
     17try: 
     18        import PySide as PyQT4 
     19except: 
     20        print "Using PyQt4 module" 
     21else: 
     22        print "Using PySide module" 
     23 
     24from PyQt4 import QtCore, QtGui, QtNetwork 
    1925 
    2026sys.path.append(os.path.join(os.getcwd(), "interface")) 
    2127from qt4_form import Ui_Form 
    2228 
    23 import pygame 
    24 #import pygame.font 
    25 import pygame.image 
    26 import pygame.locals 
    27  
    28 from twisted.internet import reactor, protocol, defer 
     29import simplejson as json 
    2930 
    3031import puzzlebox_brainstorms_configuration as configuration 
     
    4041DEBUG = 1 
    4142 
    42 FLIP = 1 
    43  
    44 DISCRETE_CONTROL_COMMANDS = configuration.DISCRETE_CONTROL_COMMANDS 
     43#FLIP = 1 
     44 
     45#DISCRETE_CONTROL_COMMANDS = configuration.DISCRETE_CONTROL_COMMANDS 
    4546 
    4647SERVER_HOST = configuration.SERVER_HOST 
    4748SERVER_PORT = configuration.SERVER_PORT 
    4849 
    49 DISPLAY_WINDOW_X_COORDINATE = configuration.DISPLAY_WINDOW_X_COORDINATE 
    50 DISPLAY_WINDOW_Y_COORDINATE = configuration.DISPLAY_WINDOW_Y_COORDINATE 
    51 DISPLAY_WINDOW_X_DIMENSION = configuration.DISPLAY_WINDOW_X_DIMENSION 
    52 DISPLAY_WINDOW_Y_DIMENSION = configuration.DISPLAY_WINDOW_Y_DIMENSION 
    53  
    54 WINDOW_BACKGROUND_COLOR = configuration.WINDOW_BACKGROUND_COLOR 
    55  
    56 IMAGE_DIRECTORY = configuration.IMAGE_DIRECTORY 
    57  
    58 BUTTON_LAYOUT = configuration.BUTTON_LAYOUT 
     50#DISPLAY_WINDOW_X_COORDINATE = configuration.DISPLAY_WINDOW_X_COORDINATE 
     51#DISPLAY_WINDOW_Y_COORDINATE = configuration.DISPLAY_WINDOW_Y_COORDINATE 
     52#DISPLAY_WINDOW_X_DIMENSION = configuration.DISPLAY_WINDOW_X_DIMENSION 
     53#DISPLAY_WINDOW_Y_DIMENSION = configuration.DISPLAY_WINDOW_Y_DIMENSION 
     54 
     55#WINDOW_BACKGROUND_COLOR = configuration.WINDOW_BACKGROUND_COLOR 
     56 
     57#IMAGE_DIRECTORY = configuration.IMAGE_DIRECTORY 
     58 
     59#BUTTON_LAYOUT = configuration.BUTTON_LAYOUT 
    5960 
    6061##################################################################### 
     
    6263##################################################################### 
    6364 
    64 class puzzlebox_brainstorms_client_interface( \ 
    65          component.puzzlebox_brainstorms_client_interface_component, \ 
    66          client.puzzlebox_brainstorms_client): 
    67          
    68         def __init__(self, log, \ 
    69                      display_window_x_coordinate, \ 
    70                      display_window_y_coordinate, \ 
    71                      display_window_x_dimension, \ 
    72                      display_window_y_dimension, \ 
    73                      window_background_color, \ 
    74                      DEBUG=DEBUG): 
    75          
     65class puzzlebox_brainstorms_client_interface_qt(QtGui.QWidget, Ui_Form, \ 
     66                                                     client.puzzlebox_brainstorms_client): 
     67         
     68        def __init__(self, log, DEBUG=DEBUG, parent = None): 
     69                 
    7670                self.log = log 
    7771                self.DEBUG = DEBUG 
    7872                 
    79                 self.display_window_x_coordinate = display_window_x_coordinate 
    80                 self.display_window_y_coordinate = display_window_y_coordinate 
    81                 self.display_window_x_dimension = display_window_x_dimension 
    82                 self.display_window_y_dimension = display_window_y_dimension 
    83                 self.window_background_color = window_background_color 
    84                  
    85                 self.server_host = configuration.SERVER_HOST 
    86                 self.server_port = configuration.SERVER_PORT 
    87                 self.max_connection_attempts = configuration.MAX_CONNECTION_ATTEMPTS 
    88                  
    89                 if (os.name == "nt") or (os.name == "dos"): 
    90                         self.operating_system = "windows" 
     73                QtGui.QWidget.__init__(self, parent) 
     74                self.setupUi(self) 
     75                 
     76                self.configureSettings() 
     77                self.connectWidgets() 
     78                self.configureNetwork() 
     79         
     80         
     81        ################################################################## 
     82         
     83        def configureSettings(self): 
     84                 
     85                # Bluetooth readout current not available 
     86                self.textLabelBluetoothStatus.setText("Status: N/A") 
     87                 
     88                # Display communication port for LEGO Mindstorms NXT device 
     89                self.lineEditBluetoothPort.setText(configuration.BLUETOOTH_DEVICE) 
     90                 
     91                # Bluetooth connection control not available 
     92                self.pushButtonBluetoothConnect.setEnabled(False) 
     93                 
     94                # Set concentration threshold value 
     95                concentration_threshold = \ 
     96                        self.getMinimumThreshold(configuration.POWER_THRESHOLDS['concentration']) 
     97                self.spinBoxConcentrationThreshold.setValue(concentration_threshold) 
     98                self.spinBoxConcentrationThreshold.update() 
     99                 
     100                # Concentration threshold value not modifiable 
     101                self.spinBoxConcentrationThreshold.setEnabled(False) 
     102                 
     103                # Set relaxation threshold value 
     104                relaxation_threshold = \ 
     105                        self.getMinimumThreshold(configuration.POWER_THRESHOLDS['relaxation']) 
     106                self.spinBoxRelaxationThreshold.setValue(relaxation_threshold) 
     107                self.spinBoxRelaxationThreshold.update() 
     108                 
     109                # Relaxation threshold value not modifiable 
     110                self.spinBoxRelaxationThreshold.setEnabled(False) 
     111         
     112         
     113        ################################################################## 
     114         
     115        def getMinimumThreshold(self, threshold): 
     116                 
     117                '''Return the minimum detection level which results 
     118                in a non-zero power setting''' 
     119                 
     120                minimum = 100 
     121                 
     122                threshold_keys = threshold.keys() 
     123                threshold_keys.sort() 
     124                threshold_keys.reverse() 
     125                 
     126                for key in threshold_keys: 
     127                         
     128                        if ((threshold[key] < minimum) and \ 
     129                                 (threshold[key] > 0)): 
     130                                minimum = key 
     131                 
     132                 
     133                return(minimum) 
     134         
     135         
     136        ################################################################## 
     137         
     138        def connectWidgets(self): 
     139                 
     140                self.connect(self.pushButtonTurnLeft, QtCore.SIGNAL("pressed()"), \ 
     141                             self.turnLeft) 
     142                self.connect(self.pushButtonTurnLeft, QtCore.SIGNAL("released()"), \ 
     143                             self.stopMotors) 
     144                 
     145                self.connect(self.pushButtonForward, QtCore.SIGNAL("pressed()"), \ 
     146                             self.driveForward) 
     147                self.connect(self.pushButtonForward, QtCore.SIGNAL("released()"), \ 
     148                             self.stopMotors) 
     149                 
     150                self.connect(self.pushButtonTurnRight, QtCore.SIGNAL("pressed()"), \ 
     151                             self.turnRight) 
     152                self.connect(self.pushButtonTurnRight, QtCore.SIGNAL("released()"), \ 
     153                             self.stopMotors) 
     154                 
     155                self.connect(self.pushButtonTurnLeftReverse, QtCore.SIGNAL("pressed()"), \ 
     156                             self.turnLeftInReverse) 
     157                self.connect(self.pushButtonTurnLeftReverse, QtCore.SIGNAL("released()"), \ 
     158                             self.stopMotors) 
     159                 
     160                self.connect(self.pushButtonReverse, QtCore.SIGNAL("pressed()"), \ 
     161                             self.driveReverse) 
     162                self.connect(self.pushButtonReverse, QtCore.SIGNAL("released()"), \ 
     163                             self.stopMotors) 
     164                 
     165                self.connect(self.pushButtonTurnRightReverse, QtCore.SIGNAL("pressed()"), \ 
     166                             self.turnRightInReverse) 
     167                self.connect(self.pushButtonTurnRightReverse, QtCore.SIGNAL("released()"), \ 
     168                             self.stopMotors) 
     169                 
     170                 
     171                self.connect(self.pushButtonBluetoothConnect, \ 
     172                                  QtCore.SIGNAL("clicked()"), \ 
     173                                  self.test) 
     174         
     175         
     176        ################################################################## 
     177         
     178        def configureNetwork(self): 
     179                 
     180                self.blockSize = 0 
     181                self.tcpSocket = QtNetwork.QTcpSocket(self) 
     182                 
     183                self.tcpSocket.readyRead.connect(self.printReply) 
     184                self.tcpSocket.error.connect(self.displayError) 
     185         
     186         
     187        ################################################################## 
     188         
     189        def printReply(self, reply=None): 
     190                 
     191                if (reply != None): 
     192                 
     193                        print "reply:", 
     194                        print reply 
     195         
     196         
     197        ################################################################## 
     198         
     199        def displayError(self, socketError): 
     200                 
     201                if socketError == QtNetwork.QAbstractSocket.RemoteHostClosedError: 
     202                        pass 
     203                 
     204                elif socketError == QtNetwork.QAbstractSocket.HostNotFoundError: 
     205                        QtGui.QMessageBox.information(self, "Puzzlebox Brainstorms Client", 
     206                                          "The server host was not found. Please check the host name and " 
     207                                          "port settings.") 
     208                 
     209                elif socketError == QtNetwork.QAbstractSocket.ConnectionRefusedError: 
     210                        QtGui.QMessageBox.information(self, "Puzzlebox Brainstorms Client", 
     211                                          "The server connection was refused by the peer. Make sure the " 
     212                                          "server is running, and check that the host name " 
     213                                          "and port settings are correct.") 
     214                 
    91215                else: 
    92                         self.operating_system = os.name 
    93                  
    94                 self.pygame = pygame 
    95                 self.screen = None 
    96                 self.FLIP = FLIP 
    97                 self.DISCRETE_CONTROL_COMMANDS = DISCRETE_CONTROL_COMMANDS 
    98                 self.image_directory = IMAGE_DIRECTORY 
    99                  
    100                 self.initialize_pygame() 
    101                  
    102                 self.pygame.FLIP = self.FLIP 
    103                  
    104                 self.buttons = {} 
    105                 self.match_key_index = {} 
    106                  
    107                 self.initialize_buttons(BUTTON_LAYOUT) 
    108                  
    109                 self.update_display() 
    110          
    111          
    112         ##################################################################### 
    113          
    114         def initialize_pygame(self): 
    115                  
    116                 if (self.operating_system != "windows"): 
    117                         os.environ['SDL_VIDEO_WINDOW_POS'] = \ 
    118                            "%i,%i" % (self.display_window_x_coordinate, \ 
    119                                       self.display_window_y_coordinate) 
    120                  
    121                 self.pygame.init() 
    122                  
    123                 if (self.FLIP): 
    124                          
    125                         self.screen = self.pygame.display.set_mode((self.display_window_x_dimension, \ 
    126                                                                     self.display_window_y_dimension), \ 
    127                                                                    pygame.HWSURFACE|pygame.DOUBLEBUF) 
    128                  
    129                 else: 
    130                          
    131                         self.screen = self.pygame.display.set_mode((self.display_window_x_dimension, \ 
    132                                                                     self.display_window_y_dimension), \ 
    133                                                                    pygame.HWSURFACE) 
    134                  
    135                  
    136                 if (self.DEBUG >= 2): 
    137                         print "Display Driver:", 
    138                         print pygame.display.get_driver() 
    139                         print 
    140                         print "Display Info:" 
    141                         print pygame.display.Info() 
    142                         #print  
    143                         #print "Windows System Info:" 
    144                         #print pygame.display.get_wm_info() 
    145                         #print 
    146                         #print "Get Flags:", 
    147                         #print pygame.display.screen.get_flags() 
    148                  
    149                  
    150                 #self.pygame.mouse.set_visible(0) 
    151                 self.pygame.mouse.set_visible(1) 
    152                  
    153                 self.pygame.display.set_caption('Puzzlebox Brainstorms - Client Interface') 
    154                  
    155                 # Set Background 
    156                 self.background = pygame.Surface(self.screen.get_size()) 
    157                 #self.background.set_alpha(0) 
    158                 self.draw_background() 
    159          
    160          
    161         ################################################################## 
    162  
    163         def draw_background(self): 
    164                  
    165                 self.background.fill(self.window_background_color) 
    166                  
    167                 self.screen.blit(self.background, (0,0)) 
    168          
    169          
    170         ##################################################################### 
    171          
    172         def initialize_buttons(self, button_layout): 
    173                  
    174                 self.buttons = {} 
    175                 self.match_key_index = {} 
    176                  
    177                 for each in button_layout.keys(): 
    178                          
    179                         button = button_layout[each] 
    180                          
    181                         if ((button['button_image'] != None) and \ 
    182                             (button['button_image'] != '.') and \ 
    183                             (button['button_image'] != '..') and \ 
    184                             (os.path.exists(os.path.join(self.image_directory, button['button_image'])))): 
    185                                  
    186                                 button_image_path = \ 
    187                                    os.path.join(self.image_directory, button['button_image']) 
    188                          
    189                         else: 
    190                                 if self.DEBUG: 
    191                                         print "Error: Button image does not exist:" 
    192                                         print "   %s" % os.path.join(self.image_directory, button['button_image']) 
    193                                 continue 
    194                          
    195                          
    196                         if ((button['activated_image'] != None) and \ 
    197                             (button['activated_image'] != '.') and \ 
    198                             (button['activated_image'] != '..') and \ 
    199                             (os.path.exists(os.path.join(self.image_directory, button['activated_image'])))): 
    200                                  
    201                                 activated_image_path = \ 
    202                                    os.path.join(self.image_directory, button['activated_image']) 
    203                          
    204                         else: 
    205                                 if self.DEBUG: 
    206                                         print "Error: Activated button image does not exist:" 
    207                                         print "   %s" % os.path.join(self.image_directory, button['activated_image']) 
    208                                 continue 
    209                          
    210                          
    211                         for match in button['match_keys']: 
    212                                 self.match_key_index[match] = button['command'] 
    213                          
    214                          
    215                         new_button = \ 
    216                            interface_button.puzzlebox_brainstorms_client_interface_button( \ 
    217                                    self.pygame, \ 
    218                                    self.screen, \ 
    219                                    button_image_path, \ 
    220                                    activated_image_path, \ 
    221                                    button['image_x'], \ 
    222                                    button['image_y'], \ 
    223                                    button['command'], \ 
    224                                    button['match_keys'], \ 
    225                                    self.DEBUG) 
    226                          
    227                          
    228                         self.buttons[ button['command'] ] = new_button 
    229          
    230          
    231         ################################################################## 
    232          
    233         def update_button(self, command, activated): 
    234                  
    235                 self.buttons[command].activated=activated 
    236                 self.buttons[command].display() 
    237                 self.update_display() 
    238          
    239          
    240         ################################################################## 
    241          
    242         def process_mouse_click(self, position, mouse_button): 
    243                  
    244                 if (mouse_button == 1): 
    245                         # first mouse button clicked 
    246                          
    247                         postion_rect = self.pygame.Rect(position, (1,1) ) 
    248                          
    249                         for each in self.buttons.keys(): 
    250                                  
    251                                 if self.buttons[each].check_collision(postion_rect): 
    252                                          
    253                                         command = self.buttons[each].command 
    254                                         self.update_button(command, activated=True) 
    255                                         self.send_command(command) 
    256          
    257          
    258         ################################################################## 
    259          
    260         def process_mouse_release(self, position, mouse_button): 
    261                  
    262                 if (mouse_button == 1): 
    263                         # first mouse button released 
    264                          
    265                         postion_rect = self.pygame.Rect(position, (1,1) ) 
    266                          
    267                         for each in self.buttons.keys(): 
    268                                  
    269                                 if self.buttons[each].check_collision(postion_rect): 
    270                                          
    271                                         command = self.buttons[each].command 
    272                                         self.update_button(command, activated=False) 
    273          
    274          
    275         ################################################################## 
    276          
    277         def release_all_buttons(self): 
    278                  
    279                 for each in self.buttons.keys(): 
    280                                  
    281                                 command = self.buttons[each].command 
    282                                 self.update_button(command, activated=False) 
    283          
    284          
    285         ################################################################## 
    286          
    287         def check_events(self): 
    288                  
    289                 for event in self.pygame.event.get(): 
    290                          
    291                         if (event.type is self.pygame.locals.QUIT): 
    292                                 reactor.stop() 
    293                          
    294                          
    295                         elif (event.type == self.pygame.locals.KEYDOWN): 
    296                                  
    297                                 if 'key' in event.dict.keys(): 
    298                                          
    299                                         key_pressed = event.dict['key'] 
    300                                          
    301                                         if (key_pressed == self.pygame.K_ESCAPE): 
    302                                                 reactor.stop() 
    303                                          
    304                                          
    305                                         elif (key_pressed in self.match_key_index.keys()): 
    306                                                  
    307                                                 # keypress matches recognized key 
    308                                                 command = self.match_key_index[key_pressed] 
    309                                                 self.update_button(command, activated=True) 
    310                                                 self.send_command(command) 
    311                          
    312                          
    313                         elif (event.type == self.pygame.locals.KEYUP): 
    314                                  
    315                                 if 'key' in event.dict.keys(): 
    316                                          
    317                                         key_pressed = event.dict['key'] 
    318                                          
    319                                         if (key_pressed in self.match_key_index.keys()): 
    320                                                  
    321                                                 # keypress matches recognized key 
    322                                                 command = self.match_key_index[key_pressed] 
    323                                                 self.update_button(command, activated=False) 
    324                          
    325                          
    326                         elif (event.type == self.pygame.locals.MOUSEBUTTONDOWN): 
    327                                  
    328                                 position = event.pos 
    329                                 mouse_button = event.button 
    330                                  
    331                                 self.process_mouse_click(position, mouse_button) 
    332                          
    333                          
    334                         elif (event.type == self.pygame.locals.MOUSEBUTTONUP): 
    335                                  
    336                                 # We release all activated buttons when a mouse button is 
    337                                 # released because its possible the user may have pressed 
    338                                 # the mouse button down while hovering over one button on 
    339                                 # the screen, then dragged the pointer while still holding 
    340                                 # down the mouse button, finally releasing it over another 
    341                                 # button on the screen. 
    342                                  
    343                                 mouse_button = event.button 
    344                                  
    345                                 if (mouse_button == 1): 
    346                                         # First mouse button released 
    347                                         self.release_all_buttons() 
    348                          
    349                          
    350                         else: 
    351                                  
    352                                 if self.DEBUG > 2: 
    353                                         print "Unrecognized event:", 
    354                                         print event 
    355                  
    356                  
    357                 # Sleep timer provides approximately 33.3 fps 
    358                 reactor.callLater(0.03, self.check_events) 
    359  
    360  
    361 ##################################################################### 
    362  
    363 class puzzlebox_brainstorms_client_interface_qt(QWidget, Ui_Form): 
    364          
    365         def __init__(self, parent = None): 
    366                  
    367                 QWidget.__init__(self, parent) 
    368                 self.setupUi(self) 
    369                  
    370                 self.connect(self.pushButtonBluetoothConnect, \ 
    371                              SIGNAL("clicked()"), \ 
    372                              self.test) 
    373                  
    374                  
     216                        QtGui.QMessageBox.information(self, "Puzzlebox Brainstorms Client", 
     217                                          "The following error occurred: %s." % self.tcpSocket.errorString()) 
     218                 
     219                self.getFortuneButton.setEnabled(True) 
     220         
     221         
     222        ################################################################## 
     223         
     224        def turnLeft(self): 
     225                self.sendCommand('turn_left') 
     226         
     227        def driveForward(self): 
     228                self.sendCommand('drive_forward') 
     229         
     230        def turnRight(self): 
     231                self.sendCommand('turn_right') 
     232         
     233        def turnLeftInReverse(self): 
     234                self.sendCommand('turn_left_in_reverse') 
     235         
     236        def driveReverse(self): 
     237                self.sendCommand('drive_reverse') 
     238         
     239        def turnRightInReverse(self): 
     240                self.sendCommand('turn_right_in_reverse') 
     241         
     242        def stopMotors(self): 
     243                self.sendCommand('stop_motors') 
     244         
     245         
     246        ################################################################## 
     247         
     248        def sendCommand(self, command): 
     249                 
     250                if self.DEBUG: 
     251                        print "Sending:", 
     252                        print command 
     253                 
     254                self.blockSize = 0 
     255                self.tcpSocket.abort() 
     256                self.tcpSocket.connectToHost(SERVER_HOST, SERVER_PORT) 
     257                 
     258                data = json.dumps(command) 
     259                self.tcpSocket.write(data) 
     260         
     261         
     262        ################################################################## 
     263         
    375264        def test(self): 
    376265                 
    377266                print "nice." 
    378267                 
    379                 self.spinBoxConcentrationThreshold.setValue(50) 
    380                 self.spinBoxConcentrationThreshold.update() 
    381                  
    382                 print dir(self.progressBarConcentration) 
    383                  
    384268                self.progressBarConcentration.setValue(50) 
    385269 
     
    395279if __name__ == '__main__': 
    396280         
    397         app = QApplication(sys.argv) 
    398          
    399         f = puzzlebox_brainstorms_client_interface_qt() 
    400         f.show() 
    401          
    402         #print dir(app) 
    403         #app.setMainWidget(f) 
     281        log = None 
     282         
     283        app = QtGui.QApplication(sys.argv) 
     284         
     285        window = puzzlebox_brainstorms_client_interface_qt(log, DEBUG) 
     286        window.show() 
     287         
    404288        app.exec_() 
    405          
    406         #window.show() 
    407          
    408         #sys.exit(app_.exec_()) 
    409          
    410         #f = Ui_Form() 
    411          
    412         #print dir(f) 
    413          
    414         #f.setupUi(self) 
    415          
    416         #f.show() 
    417         #app.setMainWidget(f) 
    418         #app.exec_loop() 
    419  
    420  
     289 
     290 
     291 
Note: See TracChangeset for help on using the changeset viewer.