Subversion Repositories Projects

Rev

Rev 601 | Rev 606 | 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
584 FredericG 6
import wx
585 FredericG 7
import wx.lib
8
import wx.lib.plot
584 FredericG 9
 
585 FredericG 10
# Needs Numeric or numarray or NumPy
11
try:
12
    import numpy.oldnumeric as _Numeric
13
except:
14
    try:
15
        import numarray as _Numeric  #if numarray is used it is renamed Numeric
16
    except:
17
        try:
18
            import Numeric as _Numeric
19
        except:
20
            msg= """
21
            This module requires the Numeric/numarray or NumPy module,
22
            which could not be imported.  It probably is not installed
23
            (it's not part of the standard Python distribution). See the
24
            Numeric Python site (http://numpy.scipy.org) for information on
25
            downloading source or binaries."""
26
            raise ImportError, "Numeric,numarray or NumPy not found. \n" + msg
27
 
584 FredericG 28
# begin wxGlade: extracode
29
# end wxGlade
30
 
31
 
32
 
601 FredericG 33
class SettingsFrame(wx.Frame):
34
    def __init__(self, *args, **kwds):
35
        # begin wxGlade: SettingsFrame.__init__
36
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
37
        wx.Frame.__init__(self, *args, **kwds)
38
        self.label_5 = wx.StaticText(self, -1, "COM Port ", style=wx.ALIGN_RIGHT)
39
        self.comPortCtrl = wx.TextCtrl(self, -1, "")
40
        self.button_5 = wx.Button(self, wx.ID_CANCEL, "")
41
        self.button_6 = wx.Button(self, wx.ID_OK, "")
42
 
43
        self.__set_properties()
44
        self.__do_layout()
45
        # end wxGlade
46
 
47
    def __set_properties(self):
48
        # begin wxGlade: SettingsFrame.__set_properties
49
        self.SetTitle("Settings")
50
        # end wxGlade
51
 
52
    def __do_layout(self):
53
        # begin wxGlade: SettingsFrame.__do_layout
54
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
55
        grid_sizer_3 = wx.GridSizer(1, 2, 0, 0)
56
        sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
57
        grid_sizer_2 = wx.GridSizer(1, 2, 4, 4)
58
        sizer_5.Add((20, 20), 0, 0, 0)
59
        sizer_6.Add((20, 20), 0, 0, 0)
60
        grid_sizer_2.Add(self.label_5, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
61
        grid_sizer_2.Add(self.comPortCtrl, 0, 0, 0)
62
        sizer_6.Add(grid_sizer_2, 0, 0, 0)
63
        sizer_6.Add((20, 20), 0, 0, 0)
64
        sizer_5.Add(sizer_6, 1, wx.EXPAND, 0)
65
        sizer_5.Add((20, 20), 0, 0, 0)
66
        grid_sizer_3.Add(self.button_5, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
67
        grid_sizer_3.Add(self.button_6, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
68
        sizer_5.Add(grid_sizer_3, 0, wx.EXPAND, 0)
69
        sizer_5.Add((20, 20), 0, 0, 0)
70
        self.SetSizer(sizer_5)
71
        sizer_5.Fit(self)
72
        self.Layout()
73
        # end wxGlade
74
 
75
# end of class SettingsFrame
76
 
77
 
587 FredericG 78
class MenuBar(wx.MenuBar):
79
    def __init__(self, *args, **kwds):
80
        # content of this block not found: did you rename this class?
81
        pass
82
 
83
    def __set_properties(self):
84
        # content of this block not found: did you rename this class?
85
        pass
86
 
87
    def __do_layout(self):
88
        # content of this block not found: did you rename this class?
89
        pass
90
 
91
# end of class MenuBar
92
 
93
 
585 FredericG 94
class wxFrame(wx.Panel):
95
    def __init__(self, *args, **kwds):
586 FredericG 96
        # content of this block not found: did you rename this class?
97
        pass
585 FredericG 98
 
99
    def __set_properties(self):
586 FredericG 100
        # content of this block not found: did you rename this class?
585 FredericG 101
        pass
102
 
103
    def __do_layout(self):
586 FredericG 104
        # content of this block not found: did you rename this class?
585 FredericG 105
        pass
106
 
107
# end of class wxFrame
108
 
109
 
110
class MyFrame(wx.Frame):
111
    def __init__(self, *args, **kwds):
112
        # content of this block not found: did you rename this class?
113
        pass
114
 
115
    def __set_properties(self):
116
        # content of this block not found: did you rename this class?
117
        pass
118
 
119
    def __do_layout(self):
120
        # content of this block not found: did you rename this class?
121
        pass
122
 
123
# end of class MyFrame
124
 
125
 
584 FredericG 126
class MainFrame(wx.Frame):
127
    def __init__(self, *args, **kwds):
128
        # begin wxGlade: MainFrame.__init__
129
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
130
        wx.Frame.__init__(self, *args, **kwds)
587 FredericG 131
 
132
        # Menu Bar
133
        self.frame_1_menubar = wx.MenuBar()
134
        wxglade_tmp_menu = wx.Menu()
135
        wxglade_tmp_menu.Append(wx.NewId(), "Exit", "", wx.ITEM_NORMAL)
136
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
137
        wxglade_tmp_menu = wx.Menu()
601 FredericG 138
        self.frame_1_menubar.Append(wxglade_tmp_menu, "Settings")
139
        wxglade_tmp_menu = wx.Menu()
587 FredericG 140
        wxglade_tmp_menu.Append(wx.NewId(), "Clear", "", wx.ITEM_NORMAL)
141
        wxglade_tmp_menu.Append(wx.NewId(), "Import", "", wx.ITEM_NORMAL)
142
        self.frame_1_menubar.Append(wxglade_tmp_menu, "TestSet")
143
        wxglade_tmp_menu = wx.Menu()
144
        self.frame_1_menubar.Append(wxglade_tmp_menu, "MK")
145
        wxglade_tmp_menu = wx.Menu()
146
        self.frame_1_menubar.Append(wxglade_tmp_menu, "Help")
147
        self.SetMenuBar(self.frame_1_menubar)
148
        # Menu Bar end
600 FredericG 149
        self.Description = wx.StaticText(self, -1, "Description")
150
        self.text_ctrl_6 = wx.TextCtrl(self, -1, "Test")
151
        self.label_37 = wx.StaticText(self, -1, "Speed(s)")
152
        self.text_ctrl_9 = wx.TextCtrl(self, -1, "100-200:10")
153
        self.label_35 = wx.StaticText(self, -1, "Motor(s)")
154
        self.text_ctrl_7 = wx.TextCtrl(self, -1, "1")
155
        self.label_38 = wx.StaticText(self, -1, "")
156
        self.text_ctrl_10 = wx.TextCtrl(self, -1, "")
157
        self.label_36 = wx.StaticText(self, -1, "Channel")
158
        self.text_ctrl_8 = wx.TextCtrl(self, -1, "6")
159
        self.label_39 = wx.StaticText(self, -1, "")
160
        self.text_ctrl_11 = wx.TextCtrl(self, -1, "")
161
        self.button_4 = wx.Button(self, -1, "Start")
162
        self.GraphPanel = wx.Panel(self, -1)
163
        self.label_40 = wx.StaticText(self, -1, "Graph Type ")
164
        self.graphTypeChoice = wx.Choice(self, -1, choices=["Raw Signal", "Filtered Signal", "Spectrum"])
165
        self.label_41 = wx.StaticText(self, -1, "Y Axis Range ")
166
        self.yAxisChoice = wx.Choice(self, -1, choices=["25", "50", "100", "200"])
586 FredericG 167
        self.TestListCtrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
584 FredericG 168
 
169
        self.__set_properties()
170
        self.__do_layout()
587 FredericG 171
 
601 FredericG 172
        self.Bind(wx.EVT_MENU, self.onClear, id=-1)
587 FredericG 173
        self.Bind(wx.EVT_MENU, self.OnImport, id=-1)
600 FredericG 174
        self.Bind(wx.EVT_CHOICE, self.onGraphTypeChange, self.graphTypeChoice)
175
        self.Bind(wx.EVT_CHOICE, self.onYAxisChange, self.yAxisChoice)
584 FredericG 176
        # end wxGlade
177
 
587 FredericG 178
    def setApp(self, app):
179
        self.app = app
585 FredericG 180
 
584 FredericG 181
    def __set_properties(self):
182
        # begin wxGlade: MainFrame.__set_properties
587 FredericG 183
        self.SetTitle("VibrationTest")
600 FredericG 184
        self.SetSize((850, 700))
185
        self.Description.SetMinSize((53, 13))
601 FredericG 186
        self.button_4.SetMinSize((80, 80))
600 FredericG 187
        self.GraphPanel.SetMinSize((800,300))
188
        self.graphTypeChoice.SetSelection(0)
189
        self.yAxisChoice.SetSelection(1)
190
        self.TestListCtrl.SetMinSize((800,300))
584 FredericG 191
        # end wxGlade
192
 
193
    def __do_layout(self):
194
        # begin wxGlade: MainFrame.__do_layout
600 FredericG 195
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
196
        sizer_8 = wx.BoxSizer(wx.VERTICAL)
197
        sizer_11 = wx.BoxSizer(wx.VERTICAL)
198
        sizer_12 = wx.BoxSizer(wx.HORIZONTAL)
199
        sizer_9 = wx.BoxSizer(wx.HORIZONTAL)
200
        sizer_10 = wx.BoxSizer(wx.HORIZONTAL)
201
        grid_sizer_1 = wx.GridSizer(3, 4, 4, 5)
202
        sizer_3.Add((20, 20), 0, 0, 0)
203
        sizer_8.Add((20, 20), 0, 0, 0)
204
        grid_sizer_1.Add(self.Description, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
584 FredericG 205
        grid_sizer_1.Add(self.text_ctrl_6, 0, 0, 0)
600 FredericG 206
        grid_sizer_1.Add(self.label_37, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
207
        grid_sizer_1.Add(self.text_ctrl_9, 0, 0, 0)
208
        grid_sizer_1.Add(self.label_35, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
584 FredericG 209
        grid_sizer_1.Add(self.text_ctrl_7, 0, 0, 0)
600 FredericG 210
        grid_sizer_1.Add(self.label_38, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
211
        grid_sizer_1.Add(self.text_ctrl_10, 0, 0, 0)
212
        grid_sizer_1.Add(self.label_36, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
584 FredericG 213
        grid_sizer_1.Add(self.text_ctrl_8, 0, 0, 0)
600 FredericG 214
        grid_sizer_1.Add(self.label_39, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
215
        grid_sizer_1.Add(self.text_ctrl_11, 0, 0, 0)
216
        sizer_9.Add(grid_sizer_1, 0, 0, 0)
217
        sizer_10.Add((50, 20), 0, 0, 0)
218
        sizer_10.Add(self.button_4, 0, wx.ALIGN_CENTER_VERTICAL, 0)
219
        sizer_9.Add(sizer_10, 1, wx.EXPAND, 0)
220
        sizer_8.Add(sizer_9, 0, 0, 0)
221
        sizer_8.Add((20, 30), 0, 0, 0)
222
        sizer_11.Add(self.GraphPanel, 1, wx.EXPAND, 0)
223
        sizer_11.Add((20, 5), 0, 0, 0)
224
        sizer_12.Add(self.label_40, 0, wx.ALIGN_CENTER_VERTICAL, 0)
225
        sizer_12.Add(self.graphTypeChoice, 0, 0, 0)
226
        sizer_12.Add((40, 20), 0, 0, 0)
227
        sizer_12.Add(self.label_41, 0, wx.ALIGN_CENTER_VERTICAL, 0)
228
        sizer_12.Add(self.yAxisChoice, 0, 0, 0)
229
        sizer_11.Add(sizer_12, 0, 0, 0)
230
        sizer_8.Add(sizer_11, 0, 0, 0)
231
        sizer_8.Add((20, 30), 0, 0, 0)
232
        sizer_8.Add(self.TestListCtrl, 1, 0, 0)
233
        sizer_8.Add((20, 20), 0, 0, 0)
234
        sizer_3.Add(sizer_8, 1, wx.EXPAND, 0)
235
        self.SetSizer(sizer_3)
584 FredericG 236
        self.Layout()
600 FredericG 237
        self.SetSize((850, 700))
584 FredericG 238
        # end wxGlade
239
 
590 FredericG 240
        # List events
241
        self.TestListCtrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTestSelected, self.TestListCtrl)
242
 
586 FredericG 243
        # Configure Graph
593 FredericG 244
        self.client = wx.lib.plot.PlotCanvas(self.GraphPanel, size=(800,300))
245
 
585 FredericG 246
        self.client.SetPointLabelFunc(self.DrawPointLabel)
247
 
248
        self.client.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL))
249
        self.client.SetFontSizeAxis(10)
250
        self.client.SetFontSizeLegend(7)
251
        self.client.setLogScale((False,False))
252
 
586 FredericG 253
 
254
        # Configure TestListCtrl
594 FredericG 255
        self.TestListCtrl.InsertColumn(0, "Description")
256
        self.TestListCtrl.InsertColumn(1, "Speed")
257
        self.TestListCtrl.InsertColumn(2, "Channel")
602 FredericG 258
        self.TestListCtrl.InsertColumn(3, "VibrationValue")
586 FredericG 259
 
585 FredericG 260
    def DrawPointLabel(self, dc, mDataDict):
261
        """This is the fuction that defines how the pointLabels are plotted
262
            dc - DC that will be passed
263
            mDataDict - Dictionary of data that you want to use for the pointLabel
264
 
265
            As an example I have decided I want a box at the curve point
266
            with some text information about the curve plotted below.
267
            Any wxDC method can be used.
268
        """
269
        # ----------
270
        dc.SetPen(wx.Pen(wx.BLACK))
271
        dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) )
272
 
273
        sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point
274
        dc.DrawRectangle( sx-5,sy-5, 10, 10)  #10by10 square centered on point
275
        px,py = mDataDict["pointXY"]
276
        cNum = mDataDict["curveNum"]
277
        pntIn = mDataDict["pIndex"]
278
        legend = mDataDict["legend"]
279
        #make a string to display
280
        s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn)
281
        dc.DrawText(s, sx , sy+1)
282
        # -----------
283
 
596 FredericG 284
 
285
    def onNewTest(self, test):
286
        index = self.TestListCtrl.InsertStringItem(sys.maxint, test.descr)
287
        self.TestListCtrl.SetStringItem(index, 1, str(test.speed))
288
        self.TestListCtrl.SetStringItem(index, 2, test.channel)
602 FredericG 289
        self.TestListCtrl.SetStringItem(index, 3, str(test.getVibValue()))
596 FredericG 290
 
291
 
590 FredericG 292
    def OnTestSelected(self, event):
293
         testId = event.m_itemIndex
294
         print "Test Selected id=%d" % (testId)
592 FredericG 295
         self.activeTestId = testId
296
         self.drawGraph()
590 FredericG 297
 
592 FredericG 298
    def drawGraph(self):
299
         vibTest = self.app.getTest(self.activeTestId)
590 FredericG 300
         nb = vibTest.getDataLen()
600 FredericG 301
         y = int(self.yAxisChoice.GetStringSelection())
590 FredericG 302
 
600 FredericG 303
         if self.graphTypeChoice.GetSelection() == 0:
599 FredericG 304
             xydata = _Numeric.linspace(0,0.09*nb,2*nb)
305
             xydata.shape = (nb, 2)
306
             xydata[:,1] = vibTest.getRawData()
600 FredericG 307
             line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
599 FredericG 308
 
309
             title = "Raw Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
310
             self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
311
             self.client.SetEnableGrid('Horizontal')
596 FredericG 312
 
600 FredericG 313
         if self.graphTypeChoice.GetSelection() == 1:
314
             xydata = _Numeric.linspace(0,0.09*nb,2*nb)
315
             xydata.shape = (nb, 2)
316
             xydata[:,1] = vibTest.getFilteredData()
317
             line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
318
 
319
             title = "Filtered Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
320
             self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
321
             self.client.SetEnableGrid('Horizontal')
322
 
323
         elif self.graphTypeChoice.GetSelection() == 2:
599 FredericG 324
             xydata = _Numeric.linspace(0,5555,nb)
325
             xydata.shape = (nb/2, 2)
326
 
327
             xydata[:,1] = vibTest.getSpectrum()
590 FredericG 328
 
599 FredericG 329
             line = wx.lib.plot.PolyLine(xydata, legend= 'Spectrum', colour='red')
600 FredericG 330
             markers = wx.lib.plot.PolyMarker(xydata, legend= '', colour='red', marker='circle',size=2)
599 FredericG 331
 
332
             title = "Spectrum: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
602 FredericG 333
             self.client.Draw(wx.lib.plot.PlotGraphics([line,markers], title, "Freq (Hz)", "Acc"), xAxis=(0,200), yAxis= (-0,y))
600 FredericG 334
             self.client.SetEnableGrid(True)
590 FredericG 335
 
599 FredericG 336
 
587 FredericG 337
    def OnImport(self, event): # wxGlade: MainFrame.<event_handler>
338
        self.app.Import()
339
 
599 FredericG 340
    def onYAxisChange(self, event): # wxGlade: MainFrame.<event_handler>
592 FredericG 341
        self.drawGraph()
342
 
600 FredericG 343
    def onGraphTypeChange(self, event): # wxGlade: MainFrame.<event_handler>
599 FredericG 344
        self.drawGraph()
345
 
601 FredericG 346
    def onClear(self, event): # wxGlade: MainFrame.<event_handler>
347
        print "Event handler `onClear' not implemented"
348
        event.Skip()
349
 
584 FredericG 350
# end of class MainFrame
351
 
352
 
586 FredericG 353
class VibTest:
596 FredericG 354
    def __init__(self, descr, motor, speed, channel, rawData):
594 FredericG 355
        self.descr = descr
356
        self.motor = motor
357
        self.speed = speed
596 FredericG 358
        self.channel = channel
599 FredericG 359
 
360
        self.dataLen = len(rawData)
361
 
590 FredericG 362
        self.rawData = _Numeric.array(rawData)
363
        self.dc = self.rawData.mean()
364
        self.rawData -= self.dc
586 FredericG 365
 
600 FredericG 366
        self.fft = _Numeric.fft.rfft(self.rawData)
367
 
368
        self.spectrum = None
369
        self.filteredData = None
599 FredericG 370
 
602 FredericG 371
        self.vibValue = None
372
 
594 FredericG 373
    def getDescr(self):
374
        return self.Descr
587 FredericG 375
 
590 FredericG 376
    def getRawData(self):
377
        return self.rawData
378
 
379
    def getDataLen(self):
380
        return self.dataLen
381
 
599 FredericG 382
    def getSpectrum(self):
600 FredericG 383
        if self.spectrum == None:
384
            self.spectrum = _Numeric.absolute(self.fft[1:self.dataLen/2+1]) / (self.dataLen/2)
385
        return self.spectrum
590 FredericG 386
 
600 FredericG 387
    def getFilteredData(self):
388
        if self.filteredData == None:
389
            tmpfft = self.fft.copy()
602 FredericG 390
            for i in range(0,5):
600 FredericG 391
                tmpfft[i] = 0
392
            for i in range(30, len(tmpfft)):
393
                tmpfft[i] = 0
394
            self.filteredData = _Numeric.fft.irfft(tmpfft)
395
        return self.filteredData
602 FredericG 396
 
397
    def getVibValue(self):
398
      if self.vibValue == None:
399
        fd = self.getFilteredData();
400
        self.vibValue = max(fd)-min(fd)
401
      return self.vibValue
599 FredericG 402
 
584 FredericG 403
class App(wx.App):
586 FredericG 404
    def __init__(self, par):
405
        self.VibTests = []
406
 
407
        wx.App.__init__(self, par)
408
 
409
 
596 FredericG 410
    def AddTest(self, descr, motor, speed, channel, rawData):
411
        test = VibTest(descr, motor, speed, channel, rawData)
586 FredericG 412
        self.VibTests.append(test)
596 FredericG 413
        self.frame_1.onNewTest(test)
586 FredericG 414
 
590 FredericG 415
    def getTest(self, testId):
416
        return self.VibTests[testId]
417
 
584 FredericG 418
    def OnInit(self):
419
        wx.InitAllImageHandlers()
586 FredericG 420
        self.frame_1 = MainFrame(None, -1, "")
587 FredericG 421
        self.frame_1.setApp(self);
586 FredericG 422
        self.SetTopWindow(self.frame_1)
423
 
587 FredericG 424
        self.frame_1.Show()
425
        return 1
426
 
427
    def Import(self):
600 FredericG 428
 
602 FredericG 429
        #filePath = "./unbal150.txt"
599 FredericG 430
        #filePath = "./nikivan.txt"
602 FredericG 431
        #filePath = "./MK1_unbal.txt"
432
        filePath = "./MK1_bal.txt"
596 FredericG 433
 
602 FredericG 434
 
596 FredericG 435
        print "Import %s" % filePath
436
 
437
        logfile = open(filePath, "r")
590 FredericG 438
        data = None
596 FredericG 439
 
440
        headers = (logfile.readline()).split(',')
441
        nbCols = len(headers)
442
        print "NbCols =", nbCols
443
 
444
        data = []
445
        descr = []
446
        speed = []
447
        channel = []
448
        for c in range(nbCols):
449
            data.append([])
450
            h = headers[c].split(' ')
451
            descr.append(h[0]);
452
            speed.append(h[1]);
453
            channel.append(h[2]);
454
 
590 FredericG 455
        for line in logfile:
456
            values = line.split(',')
596 FredericG 457
            for i in range(nbCols):
458
                data[i].append(int(values[i]))
590 FredericG 459
        logfile.close()
596 FredericG 460
 
461
        for c in range(nbCols):
599 FredericG 462
            if (len(data[c]) % 2) != 0:
463
                data[c].append(data[c][-1])
596 FredericG 464
            self.AddTest(descr[c], 0, int(speed[c]), channel[c], data[c])
590 FredericG 465
 
466
 
467
 
586 FredericG 468
 
590 FredericG 469
 
584 FredericG 470
# end of class App
471
 
472
if __name__ == "__main__":
473
    VibrationTestGui = App(0)
474
    VibrationTestGui.MainLoop()