Subversion Repositories Projects

Rev

Rev 612 | Rev 614 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 612 Rev 613
Line 11... Line 11...
11
import wx
11
import wx
12
import wx.lib
12
import wx.lib
13
import wx.lib.plot
13
import wx.lib.plot
14
import wx.lib.newevent
14
import wx.lib.newevent
Line -... Line 15...
-
 
15
 
-
 
16
import mkProto
-
 
17
 
-
 
18
 
-
 
19
 
-
 
20
CHANNEL_NAMES = ["GyroYaw", "GyroRoll", "GyroNick", "Pressure", "Batt", "AccTop", "AccRoll", "AccNick"]
15
 
21
 
16
# Needs Numeric or numarray or NumPy
22
# Needs Numeric or numarray or NumPy
17
try:
23
try:
18
    import numpy.oldnumeric as _Numeric
24
    import numpy.oldnumeric as _Numeric
19
except:
25
except:
Line 34... Line 40...
34
# begin wxGlade: extracode
40
# begin wxGlade: extracode
35
# end wxGlade
41
# end wxGlade
Line 36... Line 42...
36
 
42
 
37
 
43
 
-
 
44
# This creates a new Event class and a EVT binder function
Line 38... Line 45...
38
# This creates a new Event class and a EVT binder function
45
(MeasStatusUpdateEvent, EVT_MEAS_STATUS_UPDATE) = wx.lib.newevent.NewEvent()  
39
(MeasStatusUpdateEvent, EVT_MEAS_STATUS_UPDATE) = wx.lib.newevent.NewEvent()    
46
(MeasDataEvent, EVT_MEAS_DATA) = wx.lib.newevent.NewEvent()  
40
 
47
 
41
class MeasureDialog(wx.Dialog):
48
class MeasureDialog(wx.Dialog):
Line 52... Line 59...
52
        self.Bind(wx.EVT_BUTTON, self.onButton, self.button)
59
        self.Bind(wx.EVT_BUTTON, self.onButton, self.button)
53
        # end wxGlade
60
        # end wxGlade
Line 54... Line 61...
54
       
61
       
55
        self.running = True
62
        self.running = True
-
 
63
        self.Bind(EVT_MEAS_STATUS_UPDATE, self.OnUpdate)
-
 
64
        self.Bind(EVT_MEAS_DATA, self.OnData)
-
 
65
        # The first argument that is passed to the constructor is the parent
-
 
66
        self.app = args[0].app
Line 56... Line 67...
56
        self.Bind(EVT_MEAS_STATUS_UPDATE, self.OnUpdate)
67
        self.error = False
57
 
68
 
58
    def __set_properties(self):
69
    def __set_properties(self):
59
        # begin wxGlade: MeasureDialog.__set_properties
70
        # begin wxGlade: MeasureDialog.__set_properties
Line 75... Line 86...
75
        sizer_1.Add((20, 20), 0, 0, 0)
86
        sizer_1.Add((20, 20), 0, 0, 0)
76
        self.SetSizer(sizer_1)
87
        self.SetSizer(sizer_1)
77
        sizer_1.Fit(self)
88
        sizer_1.Fit(self)
78
        self.Layout()
89
        self.Layout()
79
        # end wxGlade
90
        # end wxGlade
-
 
91
       
-
 
92
    def OnData(self, evt):
-
 
93
        print "Received Data"
-
 
94
        self.app.AddTest2(evt.vibTest)
Line 80... Line 95...
80
 
95
 
81
    def OnUpdate(self, evt):
96
    def OnUpdate(self, evt):
82
        print "Event received"
97
        print "Status update"
-
 
98
        self.running = evt.running
-
 
99
        if evt.error:
-
 
100
            self.error = True;
-
 
101
            self.text_ctrl_1.WriteText("ERROR: ")
83
        self.running = evt.running
102
            self.text_ctrl_1.SetBackgroundColour("Red")  
84
        self.text_ctrl_1.WriteText("%s\n"%evt.msg)
103
        self.text_ctrl_1.WriteText("%s\n"%evt.msg)
-
 
104
        if (not self.running):
-
 
105
            if (not self.error):
-
 
106
                self.text_ctrl_1.SetBackgroundColour("Green")
85
        if (not self.running):
107
                self.text_ctrl_1.write(" ") # so that the background is redrawn
-
 
108
            self.button.SetLabel("Close")  
Line 86... Line 109...
86
            self.button.SetLabel("Close")  
109
           
87
       
110
       
88
    def onButton(self, event): # wxGlade: MeasureDialog.<event_handler>
111
    def onButton(self, event): # wxGlade: MeasureDialog.<event_handler>
-
 
112
        if (not self.running):
-
 
113
            self.Destroy()
Line 89... Line 114...
89
        if (not self.running):
114
        else:
Line 90... Line 115...
90
            self.Destroy()
115
            self.app.cancelMeasurement()
Line 188... Line 213...
188
        wxglade_tmp_menu = wx.Menu()
213
        wxglade_tmp_menu = wx.Menu()
189
        self.frame_1_menubar.Append(wxglade_tmp_menu, "Help")
214
        self.frame_1_menubar.Append(wxglade_tmp_menu, "Help")
190
        self.SetMenuBar(self.frame_1_menubar)
215
        self.SetMenuBar(self.frame_1_menubar)
191
        # Menu Bar end
216
        # Menu Bar end
192
        self.Description = wx.StaticText(self, -1, "Description")
217
        self.Description = wx.StaticText(self, -1, "Description")
193
        self.text_ctrl_6 = wx.TextCtrl(self, -1, "Test")
218
        self.tcDescr = wx.TextCtrl(self, -1, "Test")
194
        self.label_37 = wx.StaticText(self, -1, "Speed(s)")
219
        self.label_37 = wx.StaticText(self, -1, "Speed(s)")
195
        self.text_ctrl_9 = wx.TextCtrl(self, -1, "100-200:10")
220
        self.tcSpeeds = wx.TextCtrl(self, -1, "100-200:10")
196
        self.label_35 = wx.StaticText(self, -1, "Motor(s)")
221
        self.label_35 = wx.StaticText(self, -1, "Motor(s)")
197
        self.text_ctrl_7 = wx.TextCtrl(self, -1, "1")
222
        self.tcMotors = wx.TextCtrl(self, -1, "1")
198
        self.label_38 = wx.StaticText(self, -1, "")
223
        self.label_38 = wx.StaticText(self, -1, "")
199
        self.text_ctrl_10 = wx.TextCtrl(self, -1, "")
224
        self.text_ctrl_10 = wx.TextCtrl(self, -1, "")
200
        self.label_36 = wx.StaticText(self, -1, "Channel")
225
        self.label_36 = wx.StaticText(self, -1, "Channel(s)")
201
        self.text_ctrl_8 = wx.TextCtrl(self, -1, "6")
226
        self.tcChannels = wx.TextCtrl(self, -1, "6")
202
        self.label_39 = wx.StaticText(self, -1, "")
227
        self.label_39 = wx.StaticText(self, -1, "")
203
        self.text_ctrl_11 = wx.TextCtrl(self, -1, "")
228
        self.text_ctrl_11 = wx.TextCtrl(self, -1, "")
204
        self.button_4 = wx.Button(self, -1, "Start")
229
        self.button_4 = wx.Button(self, -1, "Start")
205
        self.GraphPanel = wx.Panel(self, -1)
230
        self.GraphPanel = wx.Panel(self, -1)
206
        self.label_40 = wx.StaticText(self, -1, "Graph Type ")
231
        self.label_40 = wx.StaticText(self, -1, "Graph Type ")
Line 245... Line 270...
245
        sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
270
        sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
246
        grid_sizer_1 = wx.GridSizer(3, 4, 4, 5)
271
        grid_sizer_1 = wx.GridSizer(3, 4, 4, 5)
247
        sizer_3.Add((20, 20), 0, 0, 0)
272
        sizer_3.Add((20, 20), 0, 0, 0)
248
        sizer_8.Add((20, 20), 0, 0, 0)
273
        sizer_8.Add((20, 20), 0, 0, 0)
249
        grid_sizer_1.Add(self.Description, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
274
        grid_sizer_1.Add(self.Description, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
250
        grid_sizer_1.Add(self.text_ctrl_6, 0, 0, 0)
275
        grid_sizer_1.Add(self.tcDescr, 0, 0, 0)
251
        grid_sizer_1.Add(self.label_37, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
276
        grid_sizer_1.Add(self.label_37, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
252
        grid_sizer_1.Add(self.text_ctrl_9, 0, 0, 0)
277
        grid_sizer_1.Add(self.tcSpeeds, 0, 0, 0)
253
        grid_sizer_1.Add(self.label_35, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
278
        grid_sizer_1.Add(self.label_35, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
254
        grid_sizer_1.Add(self.text_ctrl_7, 0, 0, 0)
279
        grid_sizer_1.Add(self.tcMotors, 0, 0, 0)
255
        grid_sizer_1.Add(self.label_38, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
280
        grid_sizer_1.Add(self.label_38, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
256
        grid_sizer_1.Add(self.text_ctrl_10, 0, 0, 0)
281
        grid_sizer_1.Add(self.text_ctrl_10, 0, 0, 0)
257
        grid_sizer_1.Add(self.label_36, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
282
        grid_sizer_1.Add(self.label_36, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
258
        grid_sizer_1.Add(self.text_ctrl_8, 0, 0, 0)
283
        grid_sizer_1.Add(self.tcChannels, 0, 0, 0)
259
        grid_sizer_1.Add(self.label_39, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
284
        grid_sizer_1.Add(self.label_39, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
260
        grid_sizer_1.Add(self.text_ctrl_11, 0, 0, 0)
285
        grid_sizer_1.Add(self.text_ctrl_11, 0, 0, 0)
261
        sizer_9.Add(grid_sizer_1, 0, 0, 0)
286
        sizer_9.Add(grid_sizer_1, 0, 0, 0)
262
        sizer_10.Add((50, 20), 0, 0, 0)
287
        sizer_10.Add((50, 20), 0, 0, 0)
263
        sizer_10.Add(self.button_4, 0, wx.ALIGN_CENTER_VERTICAL, 0)
288
        sizer_10.Add(self.button_4, 0, wx.ALIGN_CENTER_VERTICAL, 0)
Line 334... Line 359...
334
        self.TestListCtrl.SetStringItem(index, 2, test.channel)
359
        self.TestListCtrl.SetStringItem(index, 2, test.channel)
Line 335... Line 360...
335
 
360
 
336
        vv = int(test.getVibValue())
361
        vv = int(test.getVibValue())
337
        vvs = "|%s| (%d)" % ("----------------------------------------------------------------------------------------------------"[0:min(vv,100)], vv)
362
        vvs = "|%s| (%d)" % ("----------------------------------------------------------------------------------------------------"[0:min(vv,100)], vv)
338
        self.TestListCtrl.SetStringItem(index, 3, vvs)
-
 
339
        if (index == 0):
363
        self.TestListCtrl.SetStringItem(index, 3, vvs)
Line 340... Line 364...
340
            self.TestListCtrl.Select(index)
364
        self.TestListCtrl.Select(index)
341
 
365
 
342
 
366
 
Line 438... Line 462...
438
        val = dlg.ShowModal()  # this does not return until the dialog is closed.
462
        val = dlg.ShowModal()  # this does not return until the dialog is closed.
439
        dlg.Destroy()
463
        dlg.Destroy()
440
        self.app.onSettingsChanged()
464
        self.app.onSettingsChanged()
Line 441... Line 465...
441
 
465
 
-
 
466
    def onStartMeasure(self, event): # wxGlade: MainFrame.<event_handler>
-
 
467
        # Collect measure parameters
-
 
468
        mp = MeasureParameters()
-
 
469
        mp.descr = self.tcDescr.GetValue()
-
 
470
        mp.motors = map(int,self.tcMotors.GetValue().split(','))
-
 
471
        mp.channels = map(int,self.tcChannels.GetValue().split(','))
-
 
472
        s = self.tcSpeeds.GetValue()
-
 
473
        if s.count("-") == 1:
-
 
474
            # assume from-to:step format
-
 
475
            s = s.split("-")
-
 
476
            if len(s) != 2: raise Exception("Invalid format")
-
 
477
            s[1] = s[1].split(":")
-
 
478
            if len(s[1]) != 2: raise Exception("Invalid format")
-
 
479
            mp.speeds = range(int(s[0]),int(s[1][0])+int(s[1][1]),int(s[1][1]))
-
 
480
        else:
442
    def onStartMeasure(self, event): # wxGlade: MainFrame.<event_handler>
481
            mp.speeds = s.split(',')
443
   
482
       
444
        # create the dialog that will show the satus
483
        # create the dialog that will show the satus
445
        dlg = MeasureDialog(self)
484
        dlg = MeasureDialog(self)
-
 
485
        dlg.CenterOnScreen()
446
        dlg.CenterOnScreen()
486
       
447
        # Signal that application
487
        # Signal the application
-
 
488
        self.app.startMeasure(mp, dlg)
448
        self.app.startMeasure(dlg)
489
       
449
        # Show the dialog
490
        # Show the dialog
450
        val = dlg.ShowModal()  # this does not return until the dialog is closed.
491
        val = dlg.ShowModal()  # this does not return until the dialog is closed.
Line 451... Line 492...
451
        dlg.Destroy()
492
        dlg.Destroy()
Line 461... Line 502...
461
        if isinstance(self.value, int):
502
        if isinstance(self.value, int):
462
            self.value = int(newValue)
503
            self.value = int(newValue)
463
        else:
504
        else:
464
            self.value = str(newValue)
505
            self.value = str(newValue)
Line -... Line 506...
-
 
506
 
-
 
507
class MeasureParameters:
Line 465... Line 508...
465
 
508
      pass
466
 
509
 
-
 
510
class MeasureThread:
-
 
511
    def __init__(self, measureParameters, evtConsumer):
467
class MeasureThread:
512
        self.mk = mkProto.MkComm()
-
 
513
        self.param = measureParameters
-
 
514
        self.evtConsumer = evtConsumer
Line 468... Line 515...
468
    def __init__(self, evtConsumer):
515
        self.cancel = False
469
        self.evtConsumer = evtConsumer
516
        self.running = False
Line 470... Line 517...
470
       
517
       
471
    def start(self):
518
    def start(self):
-
 
519
        thread.start_new_thread(self._run, ())
472
        thread.start_new_thread(self._run, ())
520
       
473
       
521
    def stop(self):
474
    def _run(self):
522
        self.cancel = True
-
 
523
 
475
        i=0
524
    def _testCancel(self):
476
        for i in range(20):
525
        if self.cancel:
477
            time.sleep(0.5)
526
            raise Exception("Operation cancelled")
-
 
527
               
-
 
528
    def _sendEvent(self, msg, error=False):
-
 
529
        evt = MeasStatusUpdateEvent(running=self.running, msg=msg, error=error)
-
 
530
        wx.PostEvent(self.evtConsumer, evt)
-
 
531
 
-
 
532
    def _setMotorSpeed(self, speed, settlingTime):
-
 
533
        speeds = [0,0,0,0]
-
 
534
        for motor in self.param.motors:
-
 
535
            speeds[motor-1] = speed
-
 
536
        for i in range(int(settlingTime*10)):
-
 
537
          self._testCancel()
-
 
538
          self.mk.setMotorTest(speeds)
-
 
539
          time.sleep(.1)
-
 
540
       
-
 
541
                   
-
 
542
    def _run(self):
-
 
543
        self.running = True
-
 
544
        self._sendEvent("Starting test \"%s\"" % self.param.descr)    
Line -... Line 545...
-
 
545
 
-
 
546
        try:
-
 
547
            self._sendEvent("Opening SerialPort \"%s\"" % self.param.serialPort)
-
 
548
            self.mk.open(comPort=self.param.serialPort)
-
 
549
               
-
 
550
            msg = self.mk.getVersionMsg()
-
 
551
            version = msg.getVersion()
-
 
552
            self._sendEvent("Version: %d.%d" % version)
-
 
553
           
-
 
554
            msg = self.mk.getDebugMsg()
-
 
555
            voltage = msg.getVoltage()
-
 
556
            if (voltage == 0):
-
 
557
              minVoltage = 0
-
 
558
            else:
-
 
559
              if (voltage > 4.2*3):
-
 
560
                minVoltage = 4*3.5
-
 
561
              else:
-
 
562
                minVoltage = 3*3.5
-
 
563
 
-
 
564
            self._sendEvent("Voltage: %2.1fV" % voltage)
-
 
565
            self._sendEvent("Minimum Voltage: %2.1fV" % minVoltage)
-
 
566
         
-
 
567
            self._sendEvent("Starting motor(s) (speed=%d)... " % self.param.motorStartupSpeed)
-
 
568
            self._setMotorSpeed(self.param.motorStartupSpeed, self.param.motorStartupSettlingTime)
-
 
569
         
-
 
570
            for speed in self.param.speeds:
-
 
571
                self._sendEvent("Changing motor speed to %d... " % speed)
-
 
572
                self._setMotorSpeed(speed, 1)
-
 
573
               
-
 
574
                for channel in self.param.channels:
-
 
575
                    self._setMotorSpeed(speed, .1)
-
 
576
                    self._sendEvent("Getting data from channel %s" % CHANNEL_NAMES[channel])
-
 
577
                    data = self.mk.doVibrationTest(1000, channel)
-
 
578
                   
-
 
579
                    vt = VibTest(self.param.descr, self.param.motors, speed, CHANNEL_NAMES[channel], data)
-
 
580
                    evt = MeasDataEvent(vibTest = vt)
-
 
581
                    wx.PostEvent(self.evtConsumer, evt)
-
 
582
                   
-
 
583
            self._sendEvent("Done !")            
-
 
584
       
Line 478... Line 585...
478
            evt = MeasStatusUpdateEvent(running=True, msg="Hello %d" % i)
585
        except Exception, e:
479
            wx.PostEvent(self.evtConsumer, evt)
586
            self._sendEvent("Exception \"%s\"" % e, error=True)  
480
        evt = MeasStatusUpdateEvent(running=False, msg="Done")
587
               
Line 543... Line 650...
543
        wx.App.__init__(self, par)
650
        wx.App.__init__(self, par)
Line 544... Line 651...
544
 
651
 
545
        # Init settings
652
        # Init settings
546
        self.settings={}
653
        self.settings={}
-
 
654
        self.settings["serialport"] = Setting("Serial Port", "COM1")
-
 
655
        self.settings["startupspeed"] = Setting("Motor Startup Speed", 25)
-
 
656
        self.settings["startupsettling"] = Setting("Motor Startup Setting time (s)", 3)
547
        self.settings["serialport"] = Setting("Serial Port", "COM1")
657
        self.settings["serialport"] = Setting("Serial Port", "COM1")
548
        self.settings["hpf"] = Setting("HP Filter cutoff (Hz)", 50)
658
        self.settings["hpf"] = Setting("HP Filter cutoff (Hz)", 50)
Line 549... Line 659...
549
        self.settings["lpf"] = Setting("LP Filter cutoff (Hz)", 400)
659
        self.settings["lpf"] = Setting("LP Filter cutoff (Hz)", 400)
Line 561... Line 671...
561
        try:
671
        try:
562
            cp.read(App.SETTINGSFILE)
672
            cp.read(App.SETTINGSFILE)
563
            for setting in cp.items("DEFAULT"):
673
            for setting in cp.items("DEFAULT"):
564
                print " ",setting
674
                print " ",setting
565
                try:
675
                try:
566
                    self.settings[setting[0]].value = setting[1]
676
                    self.settings[setting[0]].set(setting[1])
567
                except:
677
                except:
568
                    print "WARNING, unknown setting"
678
                    print "WARNING, unknown setting"
569
        except:
679
        except:
570
            print "ERROR reading settingsfile"
680
            print "ERROR reading settingsfile"
Line 582... Line 692...
582
        file.close()
692
        file.close()
Line 583... Line 693...
583
 
693
 
584
 
694
 
585
    def onSettingsChanged(self):
695
    def onSettingsChanged(self):
-
 
696
        self.storeSettings()
-
 
697
     
-
 
698
    def AddTest2(self, vibTest):
Line 586... Line 699...
586
        self.storeSettings()
699
        self.VibTests.append(vibTest)
587
       
700
        self.frame_1.onNewTest(vibTest)
588
         
701
         
589
    def AddTest(self, descr, motor, speed, channel, rawData):
-
 
Line 590... Line 702...
590
        test = VibTest(descr, motor, speed, channel, rawData)
702
    def AddTest(self, descr, motor, speed, channel, rawData):
591
        self.VibTests.append(test)
703
        test = VibTest(descr, motor, speed, channel, rawData)
Line 592... Line 704...
592
        self.frame_1.onNewTest(test)
704
        self.AddTest2(test)
Line 635... Line 747...
635
        for c in range(nbCols):
747
        for c in range(nbCols):
636
            if (len(data[c]) % 2) != 0:
748
            if (len(data[c]) % 2) != 0:
637
                data[c].append(data[c][-1])
749
                data[c].append(data[c][-1])
638
            self.AddTest(descr[c], 0, int(speed[c]), channel[c], data[c])
750
            self.AddTest(descr[c], 0, int(speed[c]), channel[c], data[c])
Line 639... Line 751...
639
           
751
           
640
    def startMeasure(self, dialog):
752
    def startMeasure(self, measureParams, dialog):
Line -... Line 753...
-
 
753
        print "Start measuring"
-
 
754
       
-
 
755
        measureParams.serialPort = self.settings["serialport"].value
-
 
756
        measureParams.motorStartupSpeed = self.settings["startupspeed"].value
641
        print "Start measuring"
757
        measureParams.motorStartupSettlingTime = self.settings["startupsettling"].value
642
       
758
       
Line -... Line 759...
-
 
759
        self.measureThread = MeasureThread(measureParams, dialog)
-
 
760
        self.measureThread.start()
-
 
761
       
-
 
762
    def cancelMeasurement(self):
-
 
763
        print "Measuring CANCEL"