Subversion Repositories Projects

Rev

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