source: trunk/brainstorms/Puzzlebox/Brainstorms/Helicopter_Control.py @ 215

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

Brainstorms/Helicopter_Control.py:

  • hover now working!
  • fly_foward now working!
  • updated command packets
  • test_mode added
  • Property svn:executable set to *
File size: 20.4 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Puzzlebox - Brainstorms - Helicopter Control
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.22
13
14"""
15
16import sys, time
17import signal
18import serial
19
20try:
21        import PySide as PyQt4
22        from PySide import QtCore
23except:
24        print "Using PyQt4 module"
25        from PyQt4 import QtCore
26else:
27        print "Using PySide module"
28
29import Configuration as configuration
30
31#import Puzzlebox.Synapse.Protocol as protocol
32from Puzzlebox.Synapse import Protocol
33
34#####################################################################
35# Globals
36#####################################################################
37
38DEBUG = 2
39
40DEFAULT_COMMAND = 'dump_packets'
41
42SERIAL_DEVICE = '/dev/ttyUSB0'
43#SERIAL_DEVICE = '/dev/ttyACM0'
44#DEFAULT_SERIAL_BAUDRATE = 115200 # This is the closest "standard" baud rate the USB-to-Serial device will support
45#DEFAULT_SERIAL_BAUDRATE = 125000 # This is the speed reported by the forum post
46#DEFAULT_SERIAL_BAUDRATE = 128000 # This is the next closest somewhat commonly-found baud rate (though not supported by device)
47DEFAULT_SERIAL_BAUDRATE = 133333 # This is the speed reported by the logic analyzer
48#DEFAULT_SERIAL_BAUDRATE = 230400 # This is the next highest "standard" baud rate the USB-to-Serial device will support
49DEFAULT_MODE = 'read'
50
51PROTOCOL_SYNC = '\x80'
52PROTOCOL_SYNC_HEAD1 = '\x00'
53PROTOCOL_SYNC_HEAD2 = '\x00'
54PROTOCOL_ADD_SYNC_TO_HEAD = False
55PROTOCOL_ADD_SYNC_TO_TAIL = False
56PACKET_LENGTH = 14
57PAYLOAD_MINIMUM_LENGTH = 12
58PACKET_READ_SIZE = 14
59ECHO_ON = False
60
61DEVICE_BUFFER_TIMER = 22  # Frame cycle 22ms
62
63COMMAND_PACKET = {
64        'neutral':        '\x00\x00\x00\xfa\x05\xc5\x09\xde\x0e\x0b\x13\x54\x14\xaa',  # default neutral setting to use for all commands
65        'no_thrust':      '\x00\x00\x00\x5a\x05\xc5\x09\xde\x0e\x0b\x13\x54\x14\xaa',  # lowest trim setting for throttle
66        'minimum_thrust': '\x00\x00\x00\xca\x05\xc5\x09\xde\x0e\x0b\x13\x54\x14\xaa',  # lowest trim level at which throttle kicks in
67        'minimum_thrust_minus_one': '\x00\x00\x00\xc6\x05\xc5\x09\xde\x0e\x0b\x13\x54\x14\xaa',  # lowest trim level at which throttle kicks in
68        'maximum_thrust': '\x00\x00\x03\x54\x05\xc5\x09\xde\x0e\x0b\x13\x54\x14\xaa',  # maximum possible throttle and trim
69        'fifty_percent_thrust': '\x00\x00\x01\x7d\x05\xc5\x09\xde\x0e\x0b\x13\x54\x14\xaa', # calculated 50% throttle
70        'test_packet':    '\x00\x00\x03\x54\x06\x15\x09\xca\x0e\x2f\x13\x54\x14\xaa', # test packet from saleae logic screenshot
71        'maximum_forward': '\x00\x00\x00\x5a\x05\xc5\x0b\x54\x0e\x0b\x13\x54\x14\xaa', # maximum possible elevator and trim
72            'fly_forward': '\x00\x00\x01\x7d\x05\xc5\x0a\xde\x0e\x0b\x13\x54\x14\xaa', \
73}
74
75DEFAULT_COMMAND_PACKET = COMMAND_PACKET['neutral']
76
77#####################################################################
78# Classes
79#####################################################################
80
81class puzzlebox_brainstorms_helicopter_control(QtCore.QThread):
82       
83        def __init__(self, \
84                     device_address=SERIAL_DEVICE, \
85                     command=DEFAULT_COMMAND, \
86                     DEBUG=DEBUG, \
87                     parent=None):
88               
89                QtCore.QThread.__init__(self, parent)
90               
91                self.log = None
92                self.DEBUG = DEBUG
93                self.parent = parent
94               
95                self.device_address = device_address
96                self.command = command
97                self.mode = DEFAULT_MODE
98               
99                self.serial_device = None
100                self.protocol = None
101               
102               
103                #self.configureRemote()
104       
105       
106        ##################################################################
107       
108        def configureRemote(self):
109               
110                self.serial_device = \
111                        SerialDevice( \
112                                self.log, \
113                                device_address=self.device_address, \
114                                mode=self.mode, \
115                                DEBUG=self.DEBUG, \
116                                parent=self)
117               
118                self.serial_device.start()
119               
120               
121                self.protocol = \
122                        ProtocolHandler( \
123                                self.log, \
124                                self.serial_device, \
125                                mode=self.mode, \
126                                DEBUG=self.DEBUG, \
127                                parent=self)
128               
129                self.protocol.start()
130       
131       
132        ##################################################################
133       
134        def processPacket(self, packet):
135               
136                if self.DEBUG:
137                        print "data_payload:",
138                        #print packet['data_payload']
139                        print packet['data_payload'].encode("hex")
140                       
141                        #if packet['data_payload'].encode("hex") == '80acdf22cdb08b8d54':
142                                #print True
143                                #import cPickle as pickle
144                                #file = open('packet.data', 'w')
145                                #pickle.dump(packet['data_payload'], file)
146                                #file.close()
147                                #sys.exit(app.exec_())
148               
149                #if (packet != {}):
150                        #self.packet_queue.append(packet)
151                        ###self.sendPacketQueue()
152               
153                if (self.parent != None):
154                        self.parent.processPacket(self.protocol.data_packet)
155       
156       
157        ##################################################################
158       
159        def dump_packets(self):
160               
161                pass
162       
163       
164        ##################################################################
165       
166        def neutral(self):
167               
168                if self.DEBUG:
169                        print "--> Command: neutral"
170               
171                #self.protocol.command_packet = COMMAND_PACKET['neutral']
172                self.protocol.command_packet = COMMAND_PACKET['no_thrust']
173       
174       
175        ##################################################################
176       
177        def test_packet(self):
178               
179                if self.DEBUG:
180                        print "--> Command: test_packet"
181               
182                self.protocol.command_packet = COMMAND_PACKET['test_packet']
183       
184       
185        ##################################################################
186       
187        def test_mode(self):
188               
189                if self.DEBUG:
190                        print "--> Command: test_mode"
191               
192                #self.protocol.command_packet = COMMAND_PACKET['neutral']
193                #self.protocol.command_packet = COMMAND_PACKET['minimum_thrust_minus_one']
194                self.protocol.command_packet = COMMAND_PACKET['no_thrust']
195                QtCore.QThread.msleep(4 * 1000) # 4 seconds to sync
196               
197                #self.protocol.command_packet = COMMAND_PACKET['maximum_thrust']
198                self.protocol.command_packet = COMMAND_PACKET['minimum_thrust']
199                QtCore.QThread.msleep(2 * 1000) # 1 second
200               
201                #self.protocol.command_packet = COMMAND_PACKET['neutral']
202                #self.protocol.command_packet = COMMAND_PACKET['minimum_thrust_minus_one']
203                self.protocol.command_packet = COMMAND_PACKET['no_thrust']
204       
205       
206        ##################################################################
207       
208        def hover(self):
209               
210                if self.DEBUG:
211                        print "--> Command: hover"
212               
213                #self.protocol.command_packet = COMMAND_PACKET['neutral']
214                #self.protocol.command_packet = COMMAND_PACKET['minimum_thrust_minus_one']
215                self.protocol.command_packet = COMMAND_PACKET['no_thrust']
216                QtCore.QThread.msleep(5 * 1000) # 4 seconds to sync
217               
218                #self.protocol.command_packet = COMMAND_PACKET['maximum_thrust']
219                self.protocol.command_packet = COMMAND_PACKET['fifty_percent_thrust']
220                QtCore.QThread.msleep(2 * 1000) # 1 second
221               
222                #self.protocol.command_packet = COMMAND_PACKET['neutral']
223                #self.protocol.command_packet = COMMAND_PACKET['minimum_thrust_minus_one']
224                self.protocol.command_packet = COMMAND_PACKET['no_thrust']
225       
226       
227        ##################################################################
228       
229        def fly_forward(self, duration):
230               
231                if self.DEBUG:
232                        print "--> Command: fly_forward"
233               
234                self.protocol.command_packet = COMMAND_PACKET['no_thrust']
235                QtCore.QThread.msleep(5 * 1000) # 1 second
236               
237                self.protocol.command_packet = COMMAND_PACKET['fly_forward']
238                QtCore.QThread.msleep(duration * 1000) # 1 second
239               
240                self.protocol.command_packet = COMMAND_PACKET['no_thrust']
241       
242       
243        ##################################################################
244       
245        def processCommand(self):
246               
247                if (self.command == 'dump_packets') or (self.command == 'read'):
248                        self.mode = 'read'
249                else:
250                        self.mode = 'write'
251               
252               
253                self.configureRemote()
254               
255               
256                if (self.command == 'dump_packets'):
257                        self.mode = 'read'
258                        self.dump_packets()
259               
260                elif (self.command == 'neutral'):
261                        self.mode = 'write'
262                        self.neutral()
263               
264                elif (self.command == 'test_packet'):
265                        self.mode = 'write'
266                        self.test_packet()
267               
268                elif (self.command == 'test_mode'):
269                        self.mode = 'write'
270                        self.test_mode()
271               
272                elif (self.command == 'hover'):
273                        self.mode = 'write'
274                        self.hover()
275               
276                elif (self.command == 'fly_forward'):
277                        self.mode = 'write'
278                        self.fly_forward(duration=2)
279       
280       
281        ##################################################################
282       
283        def stop(self):
284               
285                #self.connection.close()
286                pass
287       
288       
289        ##################################################################
290       
291        def run(self):
292               
293                if self.DEBUG:
294                        print "<---- [%s] Main thread running" % "Helicopter Remote"
295               
296               
297                self.processCommand()
298               
299                self.exec_()
300       
301       
302        ##################################################################
303       
304        def exitThread(self, callThreadQuit=True):
305               
306                try:
307                        self.emulationTimer.stop()
308                except:
309                        pass
310               
311                if self.serial_device != None:
312                        self.serial_device.exitThread()
313               
314                if self.protocol != None:
315                        self.protocol.exitThread()
316               
317                self.socket.close()
318               
319                if callThreadQuit:
320                        QtCore.QThread.quit(self)
321               
322                if self.parent == None:
323                        sys.exit()
324
325
326#####################################################################
327#####################################################################
328
329class ProtocolHandler(QtCore.QThread):
330       
331        def __init__(self, log, \
332                               serial_device, \
333                               mode=DEFAULT_MODE, \
334                               DEBUG=DEBUG, \
335                               parent=None):
336               
337                QtCore.QThread.__init__(self,parent)
338               
339                self.log = log
340                self.DEBUG = DEBUG
341                self.parent = parent
342               
343                self.device = None
344                self.mode = mode
345               
346                self.device = serial_device
347               
348                self.packet_count = 0
349                self.bad_packets = 0
350               
351                self.keep_running = True
352               
353                self.command_packet = DEFAULT_COMMAND_PACKET
354       
355       
356        ##################################################################
357       
358        def processDataPayload(self, data_payload, payload_timestamp):
359               
360                packet_update = {}
361                packet_update['data_payload'] = data_payload
362                packet_update['payload_timestamp'] = payload_timestamp
363               
364               
365                if (self.parent != None):
366                        self.parent.processPacket(packet_update)
367       
368       
369        ##################################################################
370       
371        def parseStream(self):
372               
373                # Loop forever, parsing one packet per loop
374                packet_count = 0
375               
376                while self.keep_running:
377                       
378                        # Synchronize on [SYNC] bytes
379                        byte = self.device.read()
380                        #print byte.encode("hex")
381                       
382                        #if (byte != PROTOCOL_SYNC):
383                        if (byte != PROTOCOL_SYNC_HEAD1):
384                                continue
385                       
386                        byte = self.device.read()
387                        if (byte != PROTOCOL_SYNC_HEAD2):
388                                continue
389                       
390                       
391                        payload_timestamp = time.time()
392                       
393                        data_payload = self.device.getBuffer()
394                        data_payload = "%s%s%s" % (PROTOCOL_SYNC_HEAD1, PROTOCOL_SYNC_HEAD2, data_payload)
395                       
396                       
397                        if len(data_payload) < PAYLOAD_MINIMUM_LENGTH:
398                        #if len(data_payload) != PACKET_LENGTH:
399                                continue
400                       
401                       
402                        self.processDataPayload(data_payload, payload_timestamp)
403                       
404                       
405                        #if self.DEBUG > 1:
406                                #packet_count += 1
407                                #if packet_count >= DEBUG_PACKET_COUNT:
408                                        #print "max debugging count reached, disconnecting"
409                                        #self.keep_running = False
410                                        #self.device.stop()
411                                        #QtCore.QThread.quit(self)
412                                        ##sys.exit()
413       
414       
415        ##################################################################
416       
417        def writeStream(self):
418               
419                # Loop forever, writing one packet per loop
420                packet_count = 0
421               
422                #import cPickle as pickle
423                #file = open('packet.data', 'r')
424                #packet = pickle.loads(file.read())
425                #file.close()
426               
427                while self.keep_running:
428                       
429                        # Preppend or Append [SYNC] bytes
430                        #if PROTOCOL_ADD_SYNC_TO_HEAD:
431                                #buffer = PROTOCOL_SYNC_HEAD1
432                                #buffer += PROTOCOL_SYNC_HEAD2
433                                #buffer += self.command_packet
434                       
435                        #if PROTOCOL_ADD_SYNC_TO_TAIL:
436                                #buffer = self.command_packet
437                                #buffer += PROTOCOL_SYNC_HEAD1
438                                #buffer += PROTOCOL_SYNC_HEAD2
439                               
440                        buffer = self.command_packet
441                        self.device.buffer = buffer
442                        #self.device.buffer = packet
443                        #print packet.encode("hex")
444                       
445                        # Sleep for 20 ms
446                        # Based on 50 Hz refresh rate of Blade MLP4DSM RC device
447                        # (1/50) * 1000 = 20
448                        QtCore.QThread.msleep(DEVICE_BUFFER_TIMER)
449       
450       
451        ##################################################################
452       
453        def run(self):
454               
455                self.packet_count = 0
456                self.bad_packets = 0
457                self.session_start_timestamp = time.time()
458               
459                if self.mode == 'read':
460                        self.parseStream()
461               
462                elif self.mode == 'write':
463                        self.writeStream()
464       
465       
466        ##################################################################
467       
468        def exitThread(self, callThreadQuit=True):
469               
470                try:
471                        self.device.stop()
472                except:
473                        pass
474               
475                #self.wait()
476                if callThreadQuit:
477                        QtCore.QThread.quit(self)
478
479
480#####################################################################
481#####################################################################
482
483class SerialDevice(QtCore.QThread):
484       
485        def __init__(self, log, \
486                               device_address=SERIAL_DEVICE, \
487                               mode=DEFAULT_MODE, \
488                               DEBUG=DEBUG, \
489                               parent=None):
490               
491                QtCore.QThread.__init__(self, parent)
492               
493                self.log = log
494                self.DEBUG = DEBUG
495               
496                self.device_address = device_address
497                self.mode = mode
498                self.device = None
499                self.buffer = ''
500               
501                if (self.device_address.count(':') == 5):
502                        # Device address is a Bluetooth MAC address
503                        self.device = self.initializeBluetoothDevice()
504                else:
505                        # Device address is a serial port address
506                        self.device = self.initializeSerialDevice()
507               
508                #self.buffer_check_timer = QtCore.QTimer()
509                #QtCore.QObject.connect(self.buffer_check_timer, \
510                                       #QtCore.SIGNAL("timeout()"), \
511                                       #self.checkBuffer)
512                #self.buffer_check_timer.start(DEVICE_BUFFER_TIMER)
513               
514                self.keep_running = True
515       
516       
517        ##################################################################
518       
519        #def initializeBluetoothDevice(self):
520               
521                #socket = bluetooth.BluetoothSocket( bluetooth.RFCOMM )
522               
523                #try:
524                        #socket.connect((self.device_address, THINKGEAR_DEVICE_BLUETOOTH_CHANNEL))
525               
526                #except Exception, e:
527                        #if self.DEBUG:
528                                #print "ERROR:",
529                                #print e
530                                #sys.exit()
531               
532               
533                #return socket
534       
535       
536        ###################################################################
537       
538        def initializeSerialDevice(self):
539               
540                baudrate = DEFAULT_SERIAL_BAUDRATE
541                bytesize = 8
542                parity = 'NONE'
543                stopbits = 1
544                software_flow_control = 'f'
545                rts_cts_flow_control = 'f'
546                #timeout = 15
547                timeout = 5
548               
549                # convert bytesize
550                if (bytesize == 5):
551                        init_byte_size = serial.FIVEBITS
552                elif (bytesize == 6):
553                        init_byte_size = serial.SIXBITS
554                elif (bytesize == 7):
555                        init_byte_size = serial.SEVENBITS
556                elif (bytesize == 8):
557                        init_byte_size = serial.EIGHTBITS
558                else:
559                        #self.log.perror("Invalid value for %s modem byte size! Using default (8)" % modem_type)
560                        init_byte_size = serial.EIGHTBITS
561               
562                # convert parity
563                if (parity == 'NONE'):
564                        init_parity = serial.PARITY_NONE
565                elif (parity == 'EVEN'):
566                        init_parity = serial.PARITY_EVEN
567                elif (parity == 'ODD'):
568                        init_parity = serial.PARITY_ODD
569                else:
570                        #self.log.perror("Invalid value for %s modem parity! Using default (NONE)" % modem_type)
571                        init_parity = serial.PARITY_NONE
572               
573                # convert stopbits
574                if (stopbits == 1):
575                        init_stopbits = serial.STOPBITS_ONE
576                elif (stopbits == 2):
577                        init_stopbits = serial.STOPBITS_TWO
578                else:
579                        #self.log.perror("Invalid value for %s modem stopbits! Using default (8)" % modem_type)
580                        init_byte_size = serial.STOPBITS_ONE
581               
582                # convert software flow control
583                if (software_flow_control == 't'):
584                        init_software_flow_control = 1
585                else:
586                        init_software_flow_control = 0
587               
588                # convert rts cts flow control
589                if (rts_cts_flow_control == 't'):
590                        init_rts_cts_flow_control = 1
591                else:
592                        init_rts_cts_flow_control = 0
593               
594               
595                try:
596                       
597                        device = serialWrapper(port = self.device_address, \
598                                                    baudrate = baudrate, \
599                                                    bytesize = init_byte_size, \
600                                                    parity = init_parity, \
601                                                    stopbits = init_stopbits, \
602                                                    xonxoff = init_software_flow_control, \
603                                                    rtscts = init_rts_cts_flow_control, \
604                                                    timeout = timeout)
605               
606                except Exception, e:
607                        if self.DEBUG:
608                                print "ERROR:",
609                                print e,
610                                print self.device_address
611                                sys.exit()
612               
613               
614                #device.flushInput()
615                ##device.flushOutput()
616               
617               
618                return(device)
619       
620       
621        ###################################################################
622       
623        #def checkBuffer(self):
624               
625                #if self.DEBUG > 1:
626                        #print "INFO: Buffer size check:",
627                        #print len(self.buffer),
628                        #print "(maximum before reset is %i)" % DEVICE_BUFFER_MAX_SIZE
629               
630                #if (DEVICE_BUFFER_MAX_SIZE <= len(self.buffer)):
631                       
632                        #if self.DEBUG:
633                                #print "ERROR: Buffer size has grown too large, resetting"
634                       
635                        #self.reset()
636       
637       
638        ###################################################################
639       
640        def getBuffer(self):
641               
642                data_payload = self.buffer
643               
644                self.resetBuffer()
645               
646               
647                return(data_payload)
648       
649       
650        ###################################################################
651       
652        def resetBuffer(self):
653               
654                self.buffer = ''
655       
656       
657        ###################################################################
658       
659        def read(self, length=1):
660               
661                # Sleep for 20 ms if buffer is empty
662                # Based on 50 Hz refresh rate of Blade MLP4DSM RC device
663                # (1/50) * 1000 = 20
664                while len(self.buffer) < length:
665                        QtCore.QThread.msleep(DEVICE_BUFFER_TIMER)
666                       
667                bytes = self.buffer[:length]
668               
669                self.buffer = self.buffer[length:]
670               
671                return(bytes)
672       
673       
674        ###################################################################
675       
676        def stop(self):
677               
678                #self.buffer_check_timer.stop()
679                self.keep_running = False
680       
681       
682        ###################################################################
683       
684        def exitThread(self, callThreadQuit=True):
685               
686                self.stop()
687                self.close()
688               
689                if callThreadQuit:
690                        QtCore.QThread.quit(self)
691       
692       
693        ###################################################################
694       
695        def close(self):
696               
697                self.device.close()
698       
699       
700        ###################################################################
701       
702        def readBuffer(self):
703       
704                self.buffer = ''
705               
706                while self.keep_running:
707                       
708                       
709                        # High-Speed Echo Mode
710                        if (self.DEBUG > 3) and ECHO_ON:
711                                byte = self.device.recv(PACKET_READ_SIZE)
712                                self.device.write(byte)
713                                continue
714                       
715                       
716                        try:
717                                #byte = self.device.read()
718                                byte = self.device.recv(PACKET_READ_SIZE)
719                               
720                                #if ECHO_ON:
721                                self.device.write(byte)
722                               
723                                if (len(byte) != 0):
724                                        if self.DEBUG > 2:
725                                                print "Device read:",
726                                                print byte,
727                                                if ECHO_ON:
728                                                        print byte.encode("hex"),
729                                                        print "wrote:",
730                                                print byte.encode("hex")
731                                               
732                                        self.buffer += byte
733                       
734                        except:
735                                if self.DEBUG:
736                                        print "ERROR: failed to read from serial device"
737                                break
738               
739               
740                self.exitThread()
741       
742       
743        ###################################################################
744       
745        def writeBuffer(self):
746       
747                self.buffer = ''
748                #beacon_timer = 0
749               
750                while self.keep_running:
751                       
752                        if (len(self.buffer) != 0):
753                                buffer = self.buffer
754                                self.buffer = ''
755                               
756                               
757                                #if beacon_timer >= 750:
758                                        #buffer += '\xaa' + buffer
759                                        #beacon_timer = 0
760                               
761                               
762                                try:
763                                        self.device.write(buffer)
764                                       
765                                        if self.DEBUG > 1:
766                                                print "Device wrote:",
767                                                #print buffer,
768                                                print buffer.encode("hex")
769                               
770                                except:
771                                        if self.DEBUG:
772                                                print "ERROR: failed to write to serial device"
773                                        break
774                       
775                       
776                        # Sleep for 20 ms if buffer is empty
777                        # Based on 50 Hz refresh rate of Blade MLP4DSM RC device
778                        # (1/50) * 1000 = 20
779                        QtCore.QThread.msleep(DEVICE_BUFFER_TIMER)
780                        #beacon_timer += DEVICE_BUFFER_TIMER
781               
782               
783                self.exitThread()
784       
785       
786        ###################################################################
787       
788        def run(self):
789               
790                if self.mode == 'read':
791                        self.readBuffer()
792               
793                elif self.mode == 'write':
794                        self.writeBuffer()
795
796
797#####################################################################
798#####################################################################
799
800class serialWrapper(serial.Serial):
801       
802        #__init__(port=None, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_NONE, stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, writeTimeout=None, dsrdtr=False, interCharTimeout=None)
803       
804        def recv(self, size=1):
805               
806                return(self.read(size))
807
808
809#####################################################################
810# Functions
811#####################################################################
812
813#####################################################################
814# Main
815#####################################################################
816
817if __name__ == '__main__':
818       
819        # Perform correct KeyboardInterrupt handling
820        signal.signal(signal.SIGINT, signal.SIG_DFL)
821       
822        # Collect default settings and command line parameters
823        device = SERIAL_DEVICE
824        command = DEFAULT_COMMAND
825       
826        for each in sys.argv:
827               
828                if each.startswith("--device="):
829                        device = each[ len("--device="): ]
830                elif each.startswith("--command="):
831                        command = each[ len("--command="): ]
832       
833       
834        app = QtCore.QCoreApplication(sys.argv)
835       
836        rc = puzzlebox_brainstorms_helicopter_control(device_address=device, command=command, DEBUG=DEBUG)
837       
838        rc.start()
839       
840        sys.exit(app.exec_())
841
Note: See TracBrowser for help on using the repository browser.