Subversion Repositories Projects

Rev

Rev 613 | Rev 615 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
584 FredericG 1
#!/usr/bin/env python
2
# -*- coding: iso-8859-15 -*-
3
# generated by wxGlade 0.6.3 on Thu Sep 24 15:46:36 2009
4
 
586 FredericG 5
import sys
606 FredericG 6
import os
612 FredericG 7
import time
8
import thread
9
import ConfigParser
10
 
584 FredericG 11
import wx
585 FredericG 12
import wx.lib
13
import wx.lib.plot
612 FredericG 14
import wx.lib.newevent
584 FredericG 15
 
613 FredericG 16
import mkProto
17
 
18
 
19
 
20
CHANNEL_NAMES = ["GyroYaw", "GyroRoll", "GyroNick", "Pressure", "Batt", "AccTop", "AccRoll", "AccNick"]
21
 
585 FredericG 22
# Needs Numeric or numarray or NumPy
23
try:
24
    import numpy.oldnumeric as _Numeric
25
except:
26
    try:
27
        import numarray as _Numeric  #if numarray is used it is renamed Numeric
28
    except:
29
        try:
30
            import Numeric as _Numeric
31
        except:
32
            msg= """
33
            This module requires the Numeric/numarray or NumPy module,
34
            which could not be imported.  It probably is not installed
35
            (it's not part of the standard Python distribution). See the
36
            Numeric Python site (http://numpy.scipy.org) for information on
37
            downloading source or binaries."""
38
            raise ImportError, "Numeric,numarray or NumPy not found. \n" + msg
39
 
584 FredericG 40
# begin wxGlade: extracode
41
# end wxGlade
42
 
43
 
612 FredericG 44
# This creates a new Event class and a EVT binder function
613 FredericG 45
(MeasStatusUpdateEvent, EVT_MEAS_STATUS_UPDATE) = wx.lib.newevent.NewEvent()  
46
(MeasDataEvent, EVT_MEAS_DATA) = wx.lib.newevent.NewEvent()  
584 FredericG 47
 
612 FredericG 48
class MeasureDialog(wx.Dialog):
49
    def __init__(self, *args, **kwds):
50
        # begin wxGlade: MeasureDialog.__init__
51
        kwds["style"] = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.THICK_FRAME
52
        wx.Dialog.__init__(self, *args, **kwds)
53
        self.text_ctrl_1 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
54
        self.button = wx.Button(self, -1, "STOP")
55
 
56
        self.__set_properties()
57
        self.__do_layout()
58
 
59
        self.Bind(wx.EVT_BUTTON, self.onButton, self.button)
60
        # end wxGlade
61
 
62
        self.running = True
63
        self.Bind(EVT_MEAS_STATUS_UPDATE, self.OnUpdate)
613 FredericG 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
67
        self.error = False
612 FredericG 68
 
69
    def __set_properties(self):
70
        # begin wxGlade: MeasureDialog.__set_properties
71
        self.SetTitle("Measuring Status")
72
        self.text_ctrl_1.SetMinSize((400,300))
73
        # end wxGlade
74
 
75
    def __do_layout(self):
76
        # begin wxGlade: MeasureDialog.__do_layout
77
        sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
78
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
79
        sizer_1.Add((20, 20), 0, 0, 0)
80
        sizer_2.Add((20, 20), 0, 0, 0)
81
        sizer_2.Add(self.text_ctrl_1, 1, wx.EXPAND, 0)
82
        sizer_2.Add((20, 20), 0, 0, 0)
83
        sizer_2.Add(self.button, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
84
        sizer_2.Add((20, 20), 0, 0, 0)
85
        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
86
        sizer_1.Add((20, 20), 0, 0, 0)
87
        self.SetSizer(sizer_1)
88
        sizer_1.Fit(self)
89
        self.Layout()
90
        # end wxGlade
613 FredericG 91
 
92
    def OnData(self, evt):
93
        print "Received Data"
94
        self.app.AddTest2(evt.vibTest)
612 FredericG 95
 
96
    def OnUpdate(self, evt):
613 FredericG 97
        print "Status update"
612 FredericG 98
        self.running = evt.running
613 FredericG 99
        if evt.error:
100
            self.error = True;
101
            self.text_ctrl_1.WriteText("ERROR: ")
102
            self.text_ctrl_1.SetBackgroundColour("Red")  
612 FredericG 103
        self.text_ctrl_1.WriteText("%s\n"%evt.msg)
104
        if (not self.running):
613 FredericG 105
            if (not self.error):
106
                self.text_ctrl_1.SetBackgroundColour("Green")
107
                self.text_ctrl_1.write(" ") # so that the background is redrawn
612 FredericG 108
            self.button.SetLabel("Close")  
613 FredericG 109
 
612 FredericG 110
 
111
    def onButton(self, event): # wxGlade: MeasureDialog.<event_handler>
112
        if (not self.running):
113
            self.Destroy()
613 FredericG 114
        else:
115
            self.app.cancelMeasurement()
612 FredericG 116
 
117
# end of class MeasureDialog
118
 
119
 
607 FredericG 120
class SettingsDialog(wx.Dialog):
601 FredericG 121
    def __init__(self, *args, **kwds):
607 FredericG 122
        # begin wxGlade: SettingsDialog.__init__
123
        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
124
        wx.Dialog.__init__(self, *args, **kwds)
608 FredericG 125
        self.button_5 = wx.Button(self, wx.ID_CANCEL, "")
126
        self.button_6 = wx.Button(self, wx.ID_OK, "")
601 FredericG 127
 
128
        self.__set_properties()
129
        self.__do_layout()
611 FredericG 130
 
131
        self.Bind(wx.EVT_BUTTON, self.onOK, self.button_6)
601 FredericG 132
        # end wxGlade
133
 
608 FredericG 134
        # The first argument that is passed to the constructor is the parent
611 FredericG 135
        self.settings = args[0].app.settings
608 FredericG 136
        # Add text-boxes for all settings
611 FredericG 137
        self.tb = []
138
        self.grid_sizer_2.SetRows(len(self.settings))
139
        for setting in self.settings.iteritems():
608 FredericG 140
            lb = wx.StaticText(self, -1, setting[1].descr, style=wx.ALIGN_RIGHT)
141
            tb = wx.TextCtrl(self, -1, str(setting[1].value))
142
            self.grid_sizer_2.Add(lb, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
143
            self.grid_sizer_2.Add(tb, 0, 0, 0)
611 FredericG 144
            self.tb.append(tb)
608 FredericG 145
        self.sizer_5.Fit(self)
146
        self.Layout()
147
 
601 FredericG 148
    def __set_properties(self):
607 FredericG 149
        # begin wxGlade: SettingsDialog.__set_properties
601 FredericG 150
        self.SetTitle("Settings")
151
        # end wxGlade
152
 
153
    def __do_layout(self):
607 FredericG 154
        # begin wxGlade: SettingsDialog.__do_layout
608 FredericG 155
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
156
        grid_sizer_3 = wx.GridSizer(1, 2, 0, 0)
157
        sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
158
        grid_sizer_2 = wx.GridSizer(1, 2, 4, 4)
159
        sizer_5.Add((20, 20), 0, 0, 0)
160
        sizer_6.Add((20, 20), 0, 0, 0)
161
        sizer_6.Add(grid_sizer_2, 0, 0, 0)
162
        sizer_6.Add((20, 20), 0, 0, 0)
163
        sizer_5.Add(sizer_6, 1, wx.EXPAND, 0)
164
        sizer_5.Add((20, 20), 0, 0, 0)
165
        grid_sizer_3.Add(self.button_5, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
166
        grid_sizer_3.Add(self.button_6, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
167
        sizer_5.Add(grid_sizer_3, 0, wx.EXPAND, 0)
168
        sizer_5.Add((20, 20), 0, 0, 0)
169
        self.SetSizer(sizer_5)
170
        sizer_5.Fit(self)
601 FredericG 171
        self.Layout()
172
        # end wxGlade
173
 
608 FredericG 174
        # Store some of the items, we will need them later
175
        self.grid_sizer_2 = grid_sizer_2  
176
        self.sizer_5 = sizer_5
177
 
178
 
611 FredericG 179
    def onOK(self, event): # wxGlade: SettingsDialog.<event_handler>
180
        print "Updating parameters"
181
        try:
182
            i=0
183
            for setting in self.settings.iteritems():
184
              print setting[0], self.tb[i].GetValue()
185
              setting[1].set(self.tb[i].GetValue())
186
              i += 1
187
            event.Skip()
188
        except:
189
            wx.MessageBox("Invalid format for \"%s\" setting." % setting[1].descr)
190
 
607 FredericG 191
# end of class SettingsDialog
192
 
193
 
194
 
584 FredericG 195
class MainFrame(wx.Frame):
196
    def __init__(self, *args, **kwds):
197
        # begin wxGlade: MainFrame.__init__
198
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
199
        wx.Frame.__init__(self, *args, **kwds)
587 FredericG 200
 
201
        # Menu Bar
202
        self.frame_1_menubar = wx.MenuBar()
203
        wxglade_tmp_menu = wx.Menu()
607 FredericG 204
        wxglade_tmp_menu.Append(101, "Settings", "", wx.ITEM_NORMAL)
205
        wxglade_tmp_menu.Append(150, "Exit", "", wx.ITEM_NORMAL)
587 FredericG 206
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
207
        wxglade_tmp_menu = wx.Menu()
607 FredericG 208
        wxglade_tmp_menu.Append(301, "Clear", "", wx.ITEM_NORMAL)
209
        wxglade_tmp_menu.Append(302, "Import", "", wx.ITEM_NORMAL)
587 FredericG 210
        self.frame_1_menubar.Append(wxglade_tmp_menu, "TestSet")
211
        wxglade_tmp_menu = wx.Menu()
212
        self.frame_1_menubar.Append(wxglade_tmp_menu, "MK")
213
        wxglade_tmp_menu = wx.Menu()
214
        self.frame_1_menubar.Append(wxglade_tmp_menu, "Help")
215
        self.SetMenuBar(self.frame_1_menubar)
216
        # Menu Bar end
600 FredericG 217
        self.Description = wx.StaticText(self, -1, "Description")
613 FredericG 218
        self.tcDescr = wx.TextCtrl(self, -1, "Test")
600 FredericG 219
        self.label_37 = wx.StaticText(self, -1, "Speed(s)")
613 FredericG 220
        self.tcSpeeds = wx.TextCtrl(self, -1, "100-200:10")
600 FredericG 221
        self.label_35 = wx.StaticText(self, -1, "Motor(s)")
613 FredericG 222
        self.tcMotors = wx.TextCtrl(self, -1, "1")
600 FredericG 223
        self.label_38 = wx.StaticText(self, -1, "")
224
        self.text_ctrl_10 = wx.TextCtrl(self, -1, "")
613 FredericG 225
        self.label_36 = wx.StaticText(self, -1, "Channel(s)")
226
        self.tcChannels = wx.TextCtrl(self, -1, "6")
600 FredericG 227
        self.label_39 = wx.StaticText(self, -1, "")
228
        self.text_ctrl_11 = wx.TextCtrl(self, -1, "")
229
        self.button_4 = wx.Button(self, -1, "Start")
230
        self.GraphPanel = wx.Panel(self, -1)
231
        self.label_40 = wx.StaticText(self, -1, "Graph Type ")
232
        self.graphTypeChoice = wx.Choice(self, -1, choices=["Raw Signal", "Filtered Signal", "Spectrum"])
233
        self.label_41 = wx.StaticText(self, -1, "Y Axis Range ")
234
        self.yAxisChoice = wx.Choice(self, -1, choices=["25", "50", "100", "200"])
586 FredericG 235
        self.TestListCtrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
584 FredericG 236
 
237
        self.__set_properties()
238
        self.__do_layout()
587 FredericG 239
 
607 FredericG 240
        self.Bind(wx.EVT_MENU, self.OnSettings, id=101)
241
        self.Bind(wx.EVT_MENU, self.onClear, id=301)
242
        self.Bind(wx.EVT_MENU, self.OnImport, id=302)
612 FredericG 243
        self.Bind(wx.EVT_BUTTON, self.onStartMeasure, self.button_4)
600 FredericG 244
        self.Bind(wx.EVT_CHOICE, self.onGraphTypeChange, self.graphTypeChoice)
245
        self.Bind(wx.EVT_CHOICE, self.onYAxisChange, self.yAxisChoice)
584 FredericG 246
        # end wxGlade
247
 
587 FredericG 248
    def setApp(self, app):
249
        self.app = app
585 FredericG 250
 
584 FredericG 251
    def __set_properties(self):
252
        # begin wxGlade: MainFrame.__set_properties
587 FredericG 253
        self.SetTitle("VibrationTest")
600 FredericG 254
        self.SetSize((850, 700))
255
        self.Description.SetMinSize((53, 13))
601 FredericG 256
        self.button_4.SetMinSize((80, 80))
600 FredericG 257
        self.GraphPanel.SetMinSize((800,300))
258
        self.graphTypeChoice.SetSelection(0)
259
        self.yAxisChoice.SetSelection(1)
260
        self.TestListCtrl.SetMinSize((800,300))
584 FredericG 261
        # end wxGlade
262
 
263
    def __do_layout(self):
264
        # begin wxGlade: MainFrame.__do_layout
600 FredericG 265
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
266
        sizer_8 = wx.BoxSizer(wx.VERTICAL)
267
        sizer_11 = wx.BoxSizer(wx.VERTICAL)
268
        sizer_12 = wx.BoxSizer(wx.HORIZONTAL)
269
        sizer_9 = wx.BoxSizer(wx.HORIZONTAL)
270
        sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
271
        grid_sizer_1 = wx.GridSizer(3, 4, 4, 5)
272
        sizer_3.Add((20, 20), 0, 0, 0)
273
        sizer_8.Add((20, 20), 0, 0, 0)
274
        grid_sizer_1.Add(self.Description, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
613 FredericG 275
        grid_sizer_1.Add(self.tcDescr, 0, 0, 0)
600 FredericG 276
        grid_sizer_1.Add(self.label_37, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
613 FredericG 277
        grid_sizer_1.Add(self.tcSpeeds, 0, 0, 0)
600 FredericG 278
        grid_sizer_1.Add(self.label_35, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
613 FredericG 279
        grid_sizer_1.Add(self.tcMotors, 0, 0, 0)
600 FredericG 280
        grid_sizer_1.Add(self.label_38, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
281
        grid_sizer_1.Add(self.text_ctrl_10, 0, 0, 0)
282
        grid_sizer_1.Add(self.label_36, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
613 FredericG 283
        grid_sizer_1.Add(self.tcChannels, 0, 0, 0)
600 FredericG 284
        grid_sizer_1.Add(self.label_39, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
285
        grid_sizer_1.Add(self.text_ctrl_11, 0, 0, 0)
286
        sizer_9.Add(grid_sizer_1, 0, 0, 0)
287
        sizer_10.Add((50, 20), 0, 0, 0)
288
        sizer_10.Add(self.button_4, 0, wx.ALIGN_CENTER_VERTICAL, 0)
289
        sizer_9.Add(sizer_10, 1, wx.EXPAND, 0)
290
        sizer_8.Add(sizer_9, 0, 0, 0)
291
        sizer_8.Add((20, 30), 0, 0, 0)
292
        sizer_11.Add(self.GraphPanel, 1, wx.EXPAND, 0)
293
        sizer_11.Add((20, 5), 0, 0, 0)
294
        sizer_12.Add(self.label_40, 0, wx.ALIGN_CENTER_VERTICAL, 0)
295
        sizer_12.Add(self.graphTypeChoice, 0, 0, 0)
296
        sizer_12.Add((40, 20), 0, 0, 0)
297
        sizer_12.Add(self.label_41, 0, wx.ALIGN_CENTER_VERTICAL, 0)
298
        sizer_12.Add(self.yAxisChoice, 0, 0, 0)
299
        sizer_11.Add(sizer_12, 0, 0, 0)
300
        sizer_8.Add(sizer_11, 0, 0, 0)
301
        sizer_8.Add((20, 30), 0, 0, 0)
302
        sizer_8.Add(self.TestListCtrl, 1, 0, 0)
303
        sizer_8.Add((20, 20), 0, 0, 0)
304
        sizer_3.Add(sizer_8, 1, wx.EXPAND, 0)
305
        self.SetSizer(sizer_3)
584 FredericG 306
        self.Layout()
600 FredericG 307
        self.SetSize((850, 700))
584 FredericG 308
        # end wxGlade
309
 
590 FredericG 310
        # List events
311
        self.TestListCtrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTestSelected, self.TestListCtrl)
312
 
586 FredericG 313
        # Configure Graph
593 FredericG 314
        self.client = wx.lib.plot.PlotCanvas(self.GraphPanel, size=(800,300))
315
 
585 FredericG 316
        self.client.SetPointLabelFunc(self.DrawPointLabel)
317
 
318
        self.client.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL))
319
        self.client.SetFontSizeAxis(10)
320
        self.client.SetFontSizeLegend(7)
321
        self.client.setLogScale((False,False))
322
 
586 FredericG 323
 
324
        # Configure TestListCtrl
594 FredericG 325
        self.TestListCtrl.InsertColumn(0, "Description")
326
        self.TestListCtrl.InsertColumn(1, "Speed")
327
        self.TestListCtrl.InsertColumn(2, "Channel")
607 FredericG 328
        self.TestListCtrl.InsertColumn(3, "Vibration Value")
329
        self.TestListCtrl.SetColumnWidth(3, 500)
586 FredericG 330
 
585 FredericG 331
    def DrawPointLabel(self, dc, mDataDict):
332
        """This is the fuction that defines how the pointLabels are plotted
333
            dc - DC that will be passed
334
            mDataDict - Dictionary of data that you want to use for the pointLabel
335
 
336
            As an example I have decided I want a box at the curve point
337
            with some text information about the curve plotted below.
338
            Any wxDC method can be used.
339
        """
340
        # ----------
341
        dc.SetPen(wx.Pen(wx.BLACK))
342
        dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) )
343
 
344
        sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point
345
        dc.DrawRectangle( sx-5,sy-5, 10, 10)  #10by10 square centered on point
346
        px,py = mDataDict["pointXY"]
347
        cNum = mDataDict["curveNum"]
348
        pntIn = mDataDict["pIndex"]
349
        legend = mDataDict["legend"]
350
        #make a string to display
351
        s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn)
352
        dc.DrawText(s, sx , sy+1)
353
        # -----------
354
 
596 FredericG 355
 
356
    def onNewTest(self, test):
357
        index = self.TestListCtrl.InsertStringItem(sys.maxint, test.descr)
358
        self.TestListCtrl.SetStringItem(index, 1, str(test.speed))
359
        self.TestListCtrl.SetStringItem(index, 2, test.channel)
607 FredericG 360
 
361
        vv = int(test.getVibValue())
362
        vvs = "|%s| (%d)" % ("----------------------------------------------------------------------------------------------------"[0:min(vv,100)], vv)
363
        self.TestListCtrl.SetStringItem(index, 3, vvs)
613 FredericG 364
        self.TestListCtrl.Select(index)
596 FredericG 365
 
366
 
590 FredericG 367
    def OnTestSelected(self, event):
368
         testId = event.m_itemIndex
369
         print "Test Selected id=%d" % (testId)
592 FredericG 370
         self.activeTestId = testId
371
         self.drawGraph()
590 FredericG 372
 
592 FredericG 373
    def drawGraph(self):
607 FredericG 374
 
600 FredericG 375
         y = int(self.yAxisChoice.GetStringSelection())
590 FredericG 376
 
607 FredericG 377
         nbSelected = self.TestListCtrl.SelectedItemCount
596 FredericG 378
 
607 FredericG 379
         if nbSelected > 1:
380
             self.graphTypeChoice.Disable()
381
             x = 1
382
             data = []
383
             idx = self.TestListCtrl.GetFirstSelected()
384
             while idx != -1:
385
                 data.append([x,self.app.getTest(idx).getVibValue()])
386
                 x += 1
387
                 idx = self.TestListCtrl.GetNextSelected(idx)
388
             line = wx.lib.plot.PolyLine(data, legend= 'Vibrations', colour='red', width=2)
389
             markers = wx.lib.plot.PolyMarker(data, legend= '', colour='red', marker='circle',size=2)
390
             title = "Comparing tests"
391
             self.client.Draw(wx.lib.plot.PlotGraphics([line, markers], title, "Test", "Vibration Value"), xAxis=(1,max(x,10)), yAxis=(0,y))
600 FredericG 392
             self.client.SetEnableGrid('Horizontal')
393
 
607 FredericG 394
         else:
395
             self.graphTypeChoice.Enable()
396
             vibTest = self.app.getTest(self.activeTestId)
397
             nb = vibTest.getDataLen()
590 FredericG 398
 
607 FredericG 399
             if self.graphTypeChoice.GetSelection() == 0:
400
                 xydata = _Numeric.linspace(0,0.09*nb,2*nb)
401
                 xydata.shape = (nb, 2)
402
                 xydata[:,1] = vibTest.getRawData()
403
                 line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
404
 
405
                 title = "Raw Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
406
                 self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
407
                 self.client.SetEnableGrid('Horizontal')
599 FredericG 408
 
607 FredericG 409
             if self.graphTypeChoice.GetSelection() == 1:
410
                 xydata = _Numeric.linspace(0,0.09*nb,2*nb)
411
                 xydata.shape = (nb, 2)
412
                 xydata[:,1] = vibTest.getFilteredData()
413
                 line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
414
 
415
                 title = "Filtered Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
416
                 self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
417
                 self.client.SetEnableGrid('Horizontal')
418
 
419
             elif self.graphTypeChoice.GetSelection() == 2:
420
                 xydata = _Numeric.linspace(0,5555,nb)
421
                 xydata.shape = (nb/2, 2)
422
 
423
                 xydata[:,1] = vibTest.getSpectrum()
424
 
425
                 line = wx.lib.plot.PolyLine(xydata, legend= 'Spectrum', colour='red')
426
                 markers = wx.lib.plot.PolyMarker(xydata, legend= '', colour='red', marker='circle',size=2)
427
 
428
                 title = "Spectrum: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
429
                 self.client.Draw(wx.lib.plot.PlotGraphics([line,markers], title, "Freq (Hz)", "Acc"), xAxis=(0,200), yAxis= (-0,y))
430
                 self.client.SetEnableGrid(True)
590 FredericG 431
 
599 FredericG 432
 
587 FredericG 433
    def OnImport(self, event): # wxGlade: MainFrame.<event_handler>
606 FredericG 434
        dlg = wx.FileDialog(
435
            self, message="Choose a file",
436
            defaultDir=os.getcwd(),
437
            defaultFile="*.txt",
438
            wildcard="",
439
            style=wx.OPEN | wx.CHANGE_DIR
440
            )
441
        if dlg.ShowModal() == wx.ID_OK:
442
            paths = dlg.GetPaths();
443
            self.app.Import(paths[0])
444
        dlg.Destroy()
587 FredericG 445
 
599 FredericG 446
    def onYAxisChange(self, event): # wxGlade: MainFrame.<event_handler>
592 FredericG 447
        self.drawGraph()
448
 
600 FredericG 449
    def onGraphTypeChange(self, event): # wxGlade: MainFrame.<event_handler>
599 FredericG 450
        self.drawGraph()
451
 
601 FredericG 452
    def onClear(self, event): # wxGlade: MainFrame.<event_handler>
453
        print "Event handler `onClear' not implemented"
454
        event.Skip()
455
 
607 FredericG 456
    def OnSettings(self, event): # wxGlade: MainFrame.<event_handler>
457
        dlg = SettingsDialog(self, -1, "Sample Dialog", size=(350, 200),
458
                         #style=wx.CAPTION | wx.SYSTEM_MENU | wx.THICK_FRAME,
459
                         style=wx.DEFAULT_DIALOG_STYLE, # & ~wx.CLOSE_BOX
460
                         )
461
        dlg.CenterOnScreen()
611 FredericG 462
        val = dlg.ShowModal()  # this does not return until the dialog is closed.
607 FredericG 463
        dlg.Destroy()
611 FredericG 464
        self.app.onSettingsChanged()
607 FredericG 465
 
612 FredericG 466
    def onStartMeasure(self, event): # wxGlade: MainFrame.<event_handler>
613 FredericG 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:
614 FredericG 481
            mp.speeds = map(int,s.split(','))
482
 
613 FredericG 483
 
612 FredericG 484
        # create the dialog that will show the satus
485
        dlg = MeasureDialog(self)
486
        dlg.CenterOnScreen()
613 FredericG 487
 
488
        # Signal the application
489
        self.app.startMeasure(mp, dlg)
490
 
612 FredericG 491
        # Show the dialog
492
        val = dlg.ShowModal()  # this does not return until the dialog is closed.
493
        dlg.Destroy()
494
 
584 FredericG 495
# end of class MainFrame
496
 
607 FredericG 497
class Setting:
498
    def __init__(self, descr, defaultValue):
499
        self.descr = descr
500
        self.value = defaultValue
611 FredericG 501
 
502
    def set(self, newValue):
503
        if isinstance(self.value, int):
504
            self.value = int(newValue)
505
        else:
506
            self.value = str(newValue)
584 FredericG 507
 
613 FredericG 508
class MeasureParameters:
509
      pass
612 FredericG 510
 
511
class MeasureThread:
613 FredericG 512
    def __init__(self, measureParameters, evtConsumer):
513
        self.mk = mkProto.MkComm()
514
        self.param = measureParameters
612 FredericG 515
        self.evtConsumer = evtConsumer
613 FredericG 516
        self.cancel = False
517
        self.running = False
612 FredericG 518
 
519
    def start(self):
520
        thread.start_new_thread(self._run, ())
521
 
613 FredericG 522
    def stop(self):
523
        self.cancel = True
524
 
525
    def _testCancel(self):
526
        if self.cancel:
527
            raise Exception("Operation cancelled")
528
 
529
    def _sendEvent(self, msg, error=False):
530
        evt = MeasStatusUpdateEvent(running=self.running, msg=msg, error=error)
531
        wx.PostEvent(self.evtConsumer, evt)
532
 
533
    def _setMotorSpeed(self, speed, settlingTime):
534
        speeds = [0,0,0,0]
535
        for motor in self.param.motors:
536
            speeds[motor-1] = speed
537
        for i in range(int(settlingTime*10)):
538
          self._testCancel()
539
          self.mk.setMotorTest(speeds)
540
          time.sleep(.1)
541
 
542
 
612 FredericG 543
    def _run(self):
613 FredericG 544
        self.running = True
545
        self._sendEvent("Starting test \"%s\"" % self.param.descr)    
546
 
547
        try:
548
            self._sendEvent("Opening SerialPort \"%s\"" % self.param.serialPort)
549
            self.mk.open(comPort=self.param.serialPort)
612 FredericG 550
 
613 FredericG 551
            msg = self.mk.getVersionMsg()
552
            version = msg.getVersion()
553
            self._sendEvent("Version: %d.%d" % version)
554
 
555
            msg = self.mk.getDebugMsg()
556
            voltage = msg.getVoltage()
557
            if (voltage == 0):
558
              minVoltage = 0
559
            else:
560
              if (voltage > 4.2*3):
561
                minVoltage = 4*3.5
562
              else:
563
                minVoltage = 3*3.5
564
 
565
            self._sendEvent("Voltage: %2.1fV" % voltage)
566
            self._sendEvent("Minimum Voltage: %2.1fV" % minVoltage)
567
 
568
            self._sendEvent("Starting motor(s) (speed=%d)... " % self.param.motorStartupSpeed)
569
            self._setMotorSpeed(self.param.motorStartupSpeed, self.param.motorStartupSettlingTime)
570
 
571
            for speed in self.param.speeds:
572
                self._sendEvent("Changing motor speed to %d... " % speed)
573
                self._setMotorSpeed(speed, 1)
574
 
575
                for channel in self.param.channels:
576
                    self._setMotorSpeed(speed, .1)
577
                    self._sendEvent("Getting data from channel %s" % CHANNEL_NAMES[channel])
578
                    data = self.mk.doVibrationTest(1000, channel)
579
 
580
                    vt = VibTest(self.param.descr, self.param.motors, speed, CHANNEL_NAMES[channel], data)
581
                    evt = MeasDataEvent(vibTest = vt)
582
                    wx.PostEvent(self.evtConsumer, evt)
583
 
584
            self._sendEvent("Done !")            
612 FredericG 585
 
613 FredericG 586
        except Exception, e:
587
            self._sendEvent("Exception \"%s\"" % e, error=True)  
588
 
589
        self.running = False
590
        self._sendEvent("")    
591
 
612 FredericG 592
 
586 FredericG 593
class VibTest:
596 FredericG 594
    def __init__(self, descr, motor, speed, channel, rawData):
594 FredericG 595
        self.descr = descr
596
        self.motor = motor
597
        self.speed = speed
596 FredericG 598
        self.channel = channel
599 FredericG 599
 
600
        self.dataLen = len(rawData)
601
 
590 FredericG 602
        self.rawData = _Numeric.array(rawData)
603
        self.dc = self.rawData.mean()
604
        self.rawData -= self.dc
586 FredericG 605
 
600 FredericG 606
        self.fft = _Numeric.fft.rfft(self.rawData)
607
 
608
        self.spectrum = None
609
        self.filteredData = None
599 FredericG 610
 
602 FredericG 611
        self.vibValue = None
612
 
594 FredericG 613
    def getDescr(self):
614
        return self.Descr
587 FredericG 615
 
590 FredericG 616
    def getRawData(self):
617
        return self.rawData
618
 
619
    def getDataLen(self):
620
        return self.dataLen
621
 
599 FredericG 622
    def getSpectrum(self):
600 FredericG 623
        if self.spectrum == None:
624
            self.spectrum = _Numeric.absolute(self.fft[1:self.dataLen/2+1]) / (self.dataLen/2)
625
        return self.spectrum
590 FredericG 626
 
600 FredericG 627
    def getFilteredData(self):
628
        if self.filteredData == None:
629
            tmpfft = self.fft.copy()
602 FredericG 630
            for i in range(0,5):
600 FredericG 631
                tmpfft[i] = 0
632
            for i in range(30, len(tmpfft)):
633
                tmpfft[i] = 0
634
            self.filteredData = _Numeric.fft.irfft(tmpfft)
635
        return self.filteredData
602 FredericG 636
 
637
    def getVibValue(self):
638
      if self.vibValue == None:
614 FredericG 639
        fd = self.getFilteredData()[100:-100];
602 FredericG 640
        self.vibValue = max(fd)-min(fd)
641
      return self.vibValue
599 FredericG 642
 
607 FredericG 643
 
644
 
584 FredericG 645
class App(wx.App):
607 FredericG 646
 
647
    SETTINGSFILE = "settings.cfg"
648
 
586 FredericG 649
    def __init__(self, par):
650
        self.VibTests = []
651
        wx.App.__init__(self, par)
652
 
607 FredericG 653
        # Init settings
654
        self.settings={}
611 FredericG 655
        self.settings["serialport"] = Setting("Serial Port", "COM1")
613 FredericG 656
        self.settings["startupspeed"] = Setting("Motor Startup Speed", 25)
657
        self.settings["startupsettling"] = Setting("Motor Startup Setting time (s)", 3)
658
        self.settings["serialport"] = Setting("Serial Port", "COM1")
607 FredericG 659
        self.settings["hpf"] = Setting("HP Filter cutoff (Hz)", 50)
660
        self.settings["lpf"] = Setting("LP Filter cutoff (Hz)", 400)
661
 
662
        self.readSettings()
663
 
606 FredericG 664
        if len(sys.argv)>1:
665
            self.Import(sys.argv[1])
586 FredericG 666
 
606 FredericG 667
 
607 FredericG 668
    def readSettings(self):
669
        print "Reading settings"
670
        cp = ConfigParser.ConfigParser()
671
 
672
        try:
673
            cp.read(App.SETTINGSFILE)
674
            for setting in cp.items("DEFAULT"):
675
                print " ",setting
676
                try:
613 FredericG 677
                    self.settings[setting[0]].set(setting[1])
607 FredericG 678
                except:
679
                    print "WARNING, unknown setting"
680
        except:
681
            print "ERROR reading settingsfile"
682
 
683
 
684
    def storeSettings(self):
685
        print "Storing settings"
686
 
687
        cp = ConfigParser.ConfigParser()
688
        for setting in self.settings.iteritems():
689
            cp.set("", setting[0], setting[1].value)
690
 
691
        file = open(App.SETTINGSFILE, "w")
692
        cp.write(file)
693
        file.close()
694
 
611 FredericG 695
 
696
    def onSettingsChanged(self):
697
        self.storeSettings()
613 FredericG 698
 
699
    def AddTest2(self, vibTest):
700
        self.VibTests.append(vibTest)
701
        self.frame_1.onNewTest(vibTest)
611 FredericG 702
 
596 FredericG 703
    def AddTest(self, descr, motor, speed, channel, rawData):
704
        test = VibTest(descr, motor, speed, channel, rawData)
613 FredericG 705
        self.AddTest2(test)
586 FredericG 706
 
590 FredericG 707
    def getTest(self, testId):
708
        return self.VibTests[testId]
709
 
584 FredericG 710
    def OnInit(self):
711
        wx.InitAllImageHandlers()
586 FredericG 712
        self.frame_1 = MainFrame(None, -1, "")
587 FredericG 713
        self.frame_1.setApp(self);
586 FredericG 714
        self.SetTopWindow(self.frame_1)
715
 
607 FredericG 716
        self.frame_1.CenterOnScreen()
587 FredericG 717
        self.frame_1.Show()
718
        return 1
719
 
606 FredericG 720
    def Import(self, filePath):
596 FredericG 721
 
606 FredericG 722
        print "Importing file \"%s\"" % filePath
596 FredericG 723
 
724
        logfile = open(filePath, "r")
590 FredericG 725
        data = None
596 FredericG 726
 
727
        headers = (logfile.readline()).split(',')
728
        nbCols = len(headers)
729
        print "NbCols =", nbCols
730
 
731
        data = []
732
        descr = []
733
        speed = []
734
        channel = []
735
        for c in range(nbCols):
736
            data.append([])
737
            h = headers[c].split(' ')
738
            descr.append(h[0]);
739
            speed.append(h[1]);
740
            channel.append(h[2]);
741
 
590 FredericG 742
        for line in logfile:
743
            values = line.split(',')
596 FredericG 744
            for i in range(nbCols):
745
                data[i].append(int(values[i]))
590 FredericG 746
        logfile.close()
596 FredericG 747
 
748
        for c in range(nbCols):
599 FredericG 749
            if (len(data[c]) % 2) != 0:
750
                data[c].append(data[c][-1])
596 FredericG 751
            self.AddTest(descr[c], 0, int(speed[c]), channel[c], data[c])
612 FredericG 752
 
613 FredericG 753
    def startMeasure(self, measureParams, dialog):
612 FredericG 754
        print "Start measuring"
590 FredericG 755
 
613 FredericG 756
        measureParams.serialPort = self.settings["serialport"].value
757
        measureParams.motorStartupSpeed = self.settings["startupspeed"].value
758
        measureParams.motorStartupSettlingTime = self.settings["startupsettling"].value
759
 
760
        self.measureThread = MeasureThread(measureParams, dialog)
612 FredericG 761
        self.measureThread.start()
590 FredericG 762
 
613 FredericG 763
    def cancelMeasurement(self):
764
        print "Measuring CANCEL"
765
 
766
        self.measureThread.stop()
767
 
612 FredericG 768
 
769
 
770
 
771
 
590 FredericG 772
 
586 FredericG 773
 
590 FredericG 774
 
584 FredericG 775
# end of class App
776
 
777
if __name__ == "__main__":
778
    VibrationTestGui = App(0)
779
    VibrationTestGui.MainLoop()