Subversion Repositories Projects

Rev

Rev 612 | Rev 614 | 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:
481
            mp.speeds = s.split(',')
482
 
612 FredericG 483
        # create the dialog that will show the satus
484
        dlg = MeasureDialog(self)
485
        dlg.CenterOnScreen()
613 FredericG 486
 
487
        # Signal the application
488
        self.app.startMeasure(mp, dlg)
489
 
612 FredericG 490
        # Show the dialog
491
        val = dlg.ShowModal()  # this does not return until the dialog is closed.
492
        dlg.Destroy()
493
 
584 FredericG 494
# end of class MainFrame
495
 
607 FredericG 496
class Setting:
497
    def __init__(self, descr, defaultValue):
498
        self.descr = descr
499
        self.value = defaultValue
611 FredericG 500
 
501
    def set(self, newValue):
502
        if isinstance(self.value, int):
503
            self.value = int(newValue)
504
        else:
505
            self.value = str(newValue)
584 FredericG 506
 
613 FredericG 507
class MeasureParameters:
508
      pass
612 FredericG 509
 
510
class MeasureThread:
613 FredericG 511
    def __init__(self, measureParameters, evtConsumer):
512
        self.mk = mkProto.MkComm()
513
        self.param = measureParameters
612 FredericG 514
        self.evtConsumer = evtConsumer
613 FredericG 515
        self.cancel = False
516
        self.running = False
612 FredericG 517
 
518
    def start(self):
519
        thread.start_new_thread(self._run, ())
520
 
613 FredericG 521
    def stop(self):
522
        self.cancel = True
523
 
524
    def _testCancel(self):
525
        if self.cancel:
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
 
612 FredericG 542
    def _run(self):
613 FredericG 543
        self.running = True
544
        self._sendEvent("Starting test \"%s\"" % self.param.descr)    
545
 
546
        try:
547
            self._sendEvent("Opening SerialPort \"%s\"" % self.param.serialPort)
548
            self.mk.open(comPort=self.param.serialPort)
612 FredericG 549
 
613 FredericG 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 !")            
612 FredericG 584
 
613 FredericG 585
        except Exception, e:
586
            self._sendEvent("Exception \"%s\"" % e, error=True)  
587
 
588
        self.running = False
589
        self._sendEvent("")    
590
 
612 FredericG 591
 
586 FredericG 592
class VibTest:
596 FredericG 593
    def __init__(self, descr, motor, speed, channel, rawData):
594 FredericG 594
        self.descr = descr
595
        self.motor = motor
596
        self.speed = speed
596 FredericG 597
        self.channel = channel
599 FredericG 598
 
599
        self.dataLen = len(rawData)
600
 
590 FredericG 601
        self.rawData = _Numeric.array(rawData)
602
        self.dc = self.rawData.mean()
603
        self.rawData -= self.dc
586 FredericG 604
 
600 FredericG 605
        self.fft = _Numeric.fft.rfft(self.rawData)
606
 
607
        self.spectrum = None
608
        self.filteredData = None
599 FredericG 609
 
602 FredericG 610
        self.vibValue = None
611
 
594 FredericG 612
    def getDescr(self):
613
        return self.Descr
587 FredericG 614
 
590 FredericG 615
    def getRawData(self):
616
        return self.rawData
617
 
618
    def getDataLen(self):
619
        return self.dataLen
620
 
599 FredericG 621
    def getSpectrum(self):
600 FredericG 622
        if self.spectrum == None:
623
            self.spectrum = _Numeric.absolute(self.fft[1:self.dataLen/2+1]) / (self.dataLen/2)
624
        return self.spectrum
590 FredericG 625
 
600 FredericG 626
    def getFilteredData(self):
627
        if self.filteredData == None:
628
            tmpfft = self.fft.copy()
602 FredericG 629
            for i in range(0,5):
600 FredericG 630
                tmpfft[i] = 0
631
            for i in range(30, len(tmpfft)):
632
                tmpfft[i] = 0
633
            self.filteredData = _Numeric.fft.irfft(tmpfft)
634
        return self.filteredData
602 FredericG 635
 
636
    def getVibValue(self):
637
      if self.vibValue == None:
638
        fd = self.getFilteredData();
639
        self.vibValue = max(fd)-min(fd)
640
      return self.vibValue
599 FredericG 641
 
607 FredericG 642
 
643
 
584 FredericG 644
class App(wx.App):
607 FredericG 645
 
646
    SETTINGSFILE = "settings.cfg"
647
 
586 FredericG 648
    def __init__(self, par):
649
        self.VibTests = []
650
        wx.App.__init__(self, par)
651
 
607 FredericG 652
        # Init settings
653
        self.settings={}
611 FredericG 654
        self.settings["serialport"] = Setting("Serial Port", "COM1")
613 FredericG 655
        self.settings["startupspeed"] = Setting("Motor Startup Speed", 25)
656
        self.settings["startupsettling"] = Setting("Motor Startup Setting time (s)", 3)
657
        self.settings["serialport"] = Setting("Serial Port", "COM1")
607 FredericG 658
        self.settings["hpf"] = Setting("HP Filter cutoff (Hz)", 50)
659
        self.settings["lpf"] = Setting("LP Filter cutoff (Hz)", 400)
660
 
661
        self.readSettings()
662
 
606 FredericG 663
        if len(sys.argv)>1:
664
            self.Import(sys.argv[1])
586 FredericG 665
 
606 FredericG 666
 
607 FredericG 667
    def readSettings(self):
668
        print "Reading settings"
669
        cp = ConfigParser.ConfigParser()
670
 
671
        try:
672
            cp.read(App.SETTINGSFILE)
673
            for setting in cp.items("DEFAULT"):
674
                print " ",setting
675
                try:
613 FredericG 676
                    self.settings[setting[0]].set(setting[1])
607 FredericG 677
                except:
678
                    print "WARNING, unknown setting"
679
        except:
680
            print "ERROR reading settingsfile"
681
 
682
 
683
    def storeSettings(self):
684
        print "Storing settings"
685
 
686
        cp = ConfigParser.ConfigParser()
687
        for setting in self.settings.iteritems():
688
            cp.set("", setting[0], setting[1].value)
689
 
690
        file = open(App.SETTINGSFILE, "w")
691
        cp.write(file)
692
        file.close()
693
 
611 FredericG 694
 
695
    def onSettingsChanged(self):
696
        self.storeSettings()
613 FredericG 697
 
698
    def AddTest2(self, vibTest):
699
        self.VibTests.append(vibTest)
700
        self.frame_1.onNewTest(vibTest)
611 FredericG 701
 
596 FredericG 702
    def AddTest(self, descr, motor, speed, channel, rawData):
703
        test = VibTest(descr, motor, speed, channel, rawData)
613 FredericG 704
        self.AddTest2(test)
586 FredericG 705
 
590 FredericG 706
    def getTest(self, testId):
707
        return self.VibTests[testId]
708
 
584 FredericG 709
    def OnInit(self):
710
        wx.InitAllImageHandlers()
586 FredericG 711
        self.frame_1 = MainFrame(None, -1, "")
587 FredericG 712
        self.frame_1.setApp(self);
586 FredericG 713
        self.SetTopWindow(self.frame_1)
714
 
607 FredericG 715
        self.frame_1.CenterOnScreen()
587 FredericG 716
        self.frame_1.Show()
717
        return 1
718
 
606 FredericG 719
    def Import(self, filePath):
596 FredericG 720
 
606 FredericG 721
        print "Importing file \"%s\"" % filePath
596 FredericG 722
 
723
        logfile = open(filePath, "r")
590 FredericG 724
        data = None
596 FredericG 725
 
726
        headers = (logfile.readline()).split(',')
727
        nbCols = len(headers)
728
        print "NbCols =", nbCols
729
 
730
        data = []
731
        descr = []
732
        speed = []
733
        channel = []
734
        for c in range(nbCols):
735
            data.append([])
736
            h = headers[c].split(' ')
737
            descr.append(h[0]);
738
            speed.append(h[1]);
739
            channel.append(h[2]);
740
 
590 FredericG 741
        for line in logfile:
742
            values = line.split(',')
596 FredericG 743
            for i in range(nbCols):
744
                data[i].append(int(values[i]))
590 FredericG 745
        logfile.close()
596 FredericG 746
 
747
        for c in range(nbCols):
599 FredericG 748
            if (len(data[c]) % 2) != 0:
749
                data[c].append(data[c][-1])
596 FredericG 750
            self.AddTest(descr[c], 0, int(speed[c]), channel[c], data[c])
612 FredericG 751
 
613 FredericG 752
    def startMeasure(self, measureParams, dialog):
612 FredericG 753
        print "Start measuring"
590 FredericG 754
 
613 FredericG 755
        measureParams.serialPort = self.settings["serialport"].value
756
        measureParams.motorStartupSpeed = self.settings["startupspeed"].value
757
        measureParams.motorStartupSettlingTime = self.settings["startupsettling"].value
758
 
759
        self.measureThread = MeasureThread(measureParams, dialog)
612 FredericG 760
        self.measureThread.start()
590 FredericG 761
 
613 FredericG 762
    def cancelMeasurement(self):
763
        print "Measuring CANCEL"
764
 
765
        self.measureThread.stop()
766
 
612 FredericG 767
 
768
 
769
 
770
 
590 FredericG 771
 
586 FredericG 772
 
590 FredericG 773
 
584 FredericG 774
# end of class App
775
 
776
if __name__ == "__main__":
777
    VibrationTestGui = App(0)
778
    VibrationTestGui.MainLoop()