Subversion Repositories Projects

Rev

Rev 632 | Rev 634 | 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
623 FredericG 15
import wx.lib.agw.speedmeter as speedmeter
584 FredericG 16
 
613 FredericG 17
import mkProto
18
 
19
 
20
 
21
CHANNEL_NAMES = ["GyroYaw", "GyroRoll", "GyroNick", "Pressure", "Batt", "AccTop", "AccRoll", "AccNick"]
615 FredericG 22
FS = 11111
623 FredericG 23
pi = 3.14
613 FredericG 24
 
626 FredericG 25
rootPath = ""
26
 
585 FredericG 27
# Needs Numeric or numarray or NumPy
28
try:
29
    import numpy.oldnumeric as _Numeric
30
except:
31
    try:
32
        import numarray as _Numeric  #if numarray is used it is renamed Numeric
33
    except:
34
        try:
35
            import Numeric as _Numeric
36
        except:
37
            msg= """
38
            This module requires the Numeric/numarray or NumPy module,
39
            which could not be imported.  It probably is not installed
40
            (it's not part of the standard Python distribution). See the
41
            Numeric Python site (http://numpy.scipy.org) for information on
42
            downloading source or binaries."""
43
            raise ImportError, "Numeric,numarray or NumPy not found. \n" + msg
44
 
584 FredericG 45
# begin wxGlade: extracode
46
# end wxGlade
47
 
48
 
612 FredericG 49
# This creates a new Event class and a EVT binder function
613 FredericG 50
(MeasStatusUpdateEvent, EVT_MEAS_STATUS_UPDATE) = wx.lib.newevent.NewEvent()  
51
(MeasDataEvent, EVT_MEAS_DATA) = wx.lib.newevent.NewEvent()  
584 FredericG 52
 
612 FredericG 53
class MeasureDialog(wx.Dialog):
54
    def __init__(self, *args, **kwds):
55
        # begin wxGlade: MeasureDialog.__init__
626 FredericG 56
        kwds["style"] = wx.CAPTION|wx.RESIZE_BORDER|wx.THICK_FRAME
612 FredericG 57
        wx.Dialog.__init__(self, *args, **kwds)
58
        self.text_ctrl_1 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
59
        self.button = wx.Button(self, -1, "STOP")
623 FredericG 60
        self.voltageCtrl = speedmeter.SpeedMeter(self, extrastyle=speedmeter.SM_DRAW_HAND | speedmeter.SM_DRAW_PARTIAL_SECTORS |  speedmeter.SM_DRAW_MIDDLE_ICON )
61
        self.speedCtrl = speedmeter.SpeedMeter(self, extrastyle=speedmeter.SM_DRAW_HAND | speedmeter.SM_DRAW_PARTIAL_SECTORS | speedmeter.SM_DRAW_MIDDLE_TEXT | speedmeter.SM_DRAW_SECONDARY_TICKS)
626 FredericG 62
 
612 FredericG 63
        self.__set_properties()
64
        self.__do_layout()
65
 
66
        self.Bind(wx.EVT_BUTTON, self.onButton, self.button)
67
        # end wxGlade
68
 
626 FredericG 69
        self.button.SetFocus()
70
 
623 FredericG 71
        YELLOW = wx.Colour(255, 240, 0)
72
        BG = wx.Colour(0x80, 0x80, 0x80)
73
        # Configure Voltage Ctrl
74
        self.voltageCtrl.SetAngleRange(0,pi)
75
        intervals = range(0, 5)
76
        self.voltageCtrl.SetIntervals(intervals)
77
        colours = [wx.RED, wx.GREEN, wx.GREEN, YELLOW]
78
        self.voltageCtrl.SetIntervalColours(colours)
79
        ticks = ["", "", "", "", ""]
80
        self.voltageCtrl.SetTicks(ticks)
81
        self.voltageCtrl.SetTicksColour(wx.WHITE)
82
        self.voltageCtrl.SetHandColour(YELLOW)
83
 
626 FredericG 84
        icon = wx.Icon("%s/Resources/fuel.ico" % rootPath, wx.BITMAP_TYPE_ICO)
623 FredericG 85
        icon.SetWidth(24)
86
        icon.SetHeight(24)
87
 
88
        self.voltageCtrl.SetMiddleIcon(icon)        
89
        self.voltageCtrl.SetSpeedBackground(BG)        
90
        self.voltageCtrl.SetArcColour(wx.WHITE)
91
        self.voltageCtrl.SetSpeedValue(2)
92
 
93
 
94
        # Configure Speed Ctr;
95
        self.speedCtrl.SetAngleRange(0,pi)        
96
        intervals = range(0, 261, 20)
97
        self.speedCtrl.SetIntervals(intervals)
98
 
99
        colours = [BG]*(len(intervals)-1)
100
        for i in range(5,10):
101
          colours[i] = wx.GREEN
102
        self.speedCtrl.SetIntervalColours(colours)
103
        ticks = [str(interval) for interval in intervals]
104
        self.speedCtrl.SetTicks(ticks)
105
        self.speedCtrl.SetTicksColour(wx.WHITE)
106
        self.speedCtrl.SetNumberOfSecondaryTicks(1)
107
        self.speedCtrl.SetTicksFont(wx.Font(7, wx.SWISS, wx.NORMAL, wx.NORMAL))
108
        self.speedCtrl.SetMiddleText("Speed")
109
        self.speedCtrl.SetMiddleTextColour(wx.WHITE)
110
        self.speedCtrl.SetMiddleTextFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD))
111
        self.speedCtrl.SetHandColour(YELLOW)
112
        self.speedCtrl.SetSpeedBackground(BG)  
113
        self.speedCtrl.SetArcColour(wx.WHITE)        
114
        self.speedCtrl.SetSpeedValue(0)
115
 
116
 
612 FredericG 117
        self.running = True
118
        self.Bind(EVT_MEAS_STATUS_UPDATE, self.OnUpdate)
613 FredericG 119
        self.Bind(EVT_MEAS_DATA, self.OnData)
120
        # The first argument that is passed to the constructor is the parent
121
        self.app = args[0].app
122
        self.error = False
623 FredericG 123
        self.firstVoltage = True
612 FredericG 124
 
623 FredericG 125
 
612 FredericG 126
    def __set_properties(self):
127
        # begin wxGlade: MeasureDialog.__set_properties
128
        self.SetTitle("Measuring Status")
129
        self.text_ctrl_1.SetMinSize((400,300))
623 FredericG 130
        self.voltageCtrl.SetMinSize((50,-1))
131
        self.speedCtrl.SetMinSize((50,-1))
612 FredericG 132
        # end wxGlade
133
 
134
    def __do_layout(self):
135
        # begin wxGlade: MeasureDialog.__do_layout
136
        sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
623 FredericG 137
        sizer_4 = wx.BoxSizer(wx.VERTICAL)
612 FredericG 138
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
139
        sizer_1.Add((20, 20), 0, 0, 0)
140
        sizer_2.Add((20, 20), 0, 0, 0)
141
        sizer_2.Add(self.text_ctrl_1, 1, wx.EXPAND, 0)
142
        sizer_2.Add((20, 20), 0, 0, 0)
143
        sizer_2.Add(self.button, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
144
        sizer_2.Add((20, 20), 0, 0, 0)
145
        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
146
        sizer_1.Add((20, 20), 0, 0, 0)
623 FredericG 147
        sizer_4.Add(self.voltageCtrl, 1, wx.EXPAND, 0)
148
        sizer_4.Add(self.speedCtrl, 1, wx.EXPAND, 0)
149
        sizer_1.Add(sizer_4, 1, wx.EXPAND, 0)
150
        sizer_1.Add((20, 20), 0, 0, 0)
612 FredericG 151
        self.SetSizer(sizer_1)
152
        sizer_1.Fit(self)
153
        self.Layout()
154
        # end wxGlade
613 FredericG 155
 
156
    def OnData(self, evt):
157
        print "Received Data"
158
        self.app.AddTest2(evt.vibTest)
623 FredericG 159
 
612 FredericG 160
    def OnUpdate(self, evt):
613 FredericG 161
        print "Status update"
612 FredericG 162
        self.running = evt.running
613 FredericG 163
        if evt.error:
164
            self.error = True;
165
            self.text_ctrl_1.WriteText("ERROR: ")
166
            self.text_ctrl_1.SetBackgroundColour("Red")  
612 FredericG 167
        self.text_ctrl_1.WriteText("%s\n"%evt.msg)
168
        if (not self.running):
613 FredericG 169
            if (not self.error):
170
                self.text_ctrl_1.SetBackgroundColour("Green")
171
                self.text_ctrl_1.write(" ") # so that the background is redrawn
623 FredericG 172
            self.button.SetLabel("Close")
613 FredericG 173
 
623 FredericG 174
        if evt.speed != None:
175
            self.speedCtrl.SetSpeedValue(evt.speed)
176
 
177
        if evt.voltage != None:
178
            vmin,vmax,v = evt.voltage
179
            if self.firstVoltage:
180
                ticks = ["", "%.1f V"%vmin, "", "%.1f V"%vmax, ""]
181
                self.voltageCtrl.SetTicks(ticks)
182
                self.firstVoltage = False
183
            i = (v-vmin)/(vmax-vmin)  # 0..1
184
            i *= 2
185
            i = i+1
629 FredericG 186
            i = min(max(i,0.1),4.9)
623 FredericG 187
            self.voltageCtrl.SetSpeedValue(i)
188
 
189
 
612 FredericG 190
 
191
    def onButton(self, event): # wxGlade: MeasureDialog.<event_handler>
192
        if (not self.running):
193
            self.Destroy()
613 FredericG 194
        else:
195
            self.app.cancelMeasurement()
612 FredericG 196
 
197
# end of class MeasureDialog
198
 
199
 
607 FredericG 200
class SettingsDialog(wx.Dialog):
601 FredericG 201
    def __init__(self, *args, **kwds):
607 FredericG 202
        # begin wxGlade: SettingsDialog.__init__
203
        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
204
        wx.Dialog.__init__(self, *args, **kwds)
608 FredericG 205
        self.button_5 = wx.Button(self, wx.ID_CANCEL, "")
206
        self.button_6 = wx.Button(self, wx.ID_OK, "")
601 FredericG 207
 
208
        self.__set_properties()
209
        self.__do_layout()
611 FredericG 210
 
211
        self.Bind(wx.EVT_BUTTON, self.onOK, self.button_6)
601 FredericG 212
        # end wxGlade
213
 
608 FredericG 214
        # The first argument that is passed to the constructor is the parent
611 FredericG 215
        self.settings = args[0].app.settings
608 FredericG 216
        # Add text-boxes for all settings
611 FredericG 217
        self.tb = []
218
        self.grid_sizer_2.SetRows(len(self.settings))
219
        for setting in self.settings.iteritems():
608 FredericG 220
            lb = wx.StaticText(self, -1, setting[1].descr, style=wx.ALIGN_RIGHT)
221
            tb = wx.TextCtrl(self, -1, str(setting[1].value))
222
            self.grid_sizer_2.Add(lb, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
223
            self.grid_sizer_2.Add(tb, 0, 0, 0)
611 FredericG 224
            self.tb.append(tb)
608 FredericG 225
        self.sizer_5.Fit(self)
226
        self.Layout()
227
 
601 FredericG 228
    def __set_properties(self):
607 FredericG 229
        # begin wxGlade: SettingsDialog.__set_properties
601 FredericG 230
        self.SetTitle("Settings")
231
        # end wxGlade
232
 
233
    def __do_layout(self):
607 FredericG 234
        # begin wxGlade: SettingsDialog.__do_layout
608 FredericG 235
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
236
        grid_sizer_3 = wx.GridSizer(1, 2, 0, 0)
237
        sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
238
        grid_sizer_2 = wx.GridSizer(1, 2, 4, 4)
239
        sizer_5.Add((20, 20), 0, 0, 0)
240
        sizer_6.Add((20, 20), 0, 0, 0)
241
        sizer_6.Add(grid_sizer_2, 0, 0, 0)
242
        sizer_6.Add((20, 20), 0, 0, 0)
243
        sizer_5.Add(sizer_6, 1, wx.EXPAND, 0)
244
        sizer_5.Add((20, 20), 0, 0, 0)
245
        grid_sizer_3.Add(self.button_5, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
246
        grid_sizer_3.Add(self.button_6, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
247
        sizer_5.Add(grid_sizer_3, 0, wx.EXPAND, 0)
248
        sizer_5.Add((20, 20), 0, 0, 0)
249
        self.SetSizer(sizer_5)
250
        sizer_5.Fit(self)
601 FredericG 251
        self.Layout()
252
        # end wxGlade
253
 
608 FredericG 254
        # Store some of the items, we will need them later
255
        self.grid_sizer_2 = grid_sizer_2  
256
        self.sizer_5 = sizer_5
257
 
258
 
611 FredericG 259
    def onOK(self, event): # wxGlade: SettingsDialog.<event_handler>
260
        print "Updating parameters"
261
        try:
262
            i=0
263
            for setting in self.settings.iteritems():
264
              print setting[0], self.tb[i].GetValue()
265
              setting[1].set(self.tb[i].GetValue())
266
              i += 1
267
            event.Skip()
268
        except:
269
            wx.MessageBox("Invalid format for \"%s\" setting." % setting[1].descr)
270
 
607 FredericG 271
# end of class SettingsDialog
272
 
273
 
274
 
584 FredericG 275
class MainFrame(wx.Frame):
276
    def __init__(self, *args, **kwds):
277
        # begin wxGlade: MainFrame.__init__
278
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
279
        wx.Frame.__init__(self, *args, **kwds)
587 FredericG 280
 
281
        # Menu Bar
282
        self.frame_1_menubar = wx.MenuBar()
283
        wxglade_tmp_menu = wx.Menu()
607 FredericG 284
        wxglade_tmp_menu.Append(101, "Settings", "", wx.ITEM_NORMAL)
616 FredericG 285
        wxglade_tmp_menu.AppendSeparator()
607 FredericG 286
        wxglade_tmp_menu.Append(150, "Exit", "", wx.ITEM_NORMAL)
587 FredericG 287
        self.frame_1_menubar.Append(wxglade_tmp_menu, "File")
288
        wxglade_tmp_menu = wx.Menu()
616 FredericG 289
        wxglade_tmp_menu.Append(301, "Clear All", "", wx.ITEM_NORMAL)
290
        wxglade_tmp_menu.Append(302, "Clear Selected", "", wx.ITEM_NORMAL)
291
        wxglade_tmp_menu.AppendSeparator()
627 FredericG 292
        wxglade_tmp_menu.Append(310, "Select All", "", wx.ITEM_NORMAL)
293
        wxglade_tmp_menu.AppendSeparator()
616 FredericG 294
        wxglade_tmp_menu.Append(303, "Load", "", wx.ITEM_NORMAL)
295
        wxglade_tmp_menu.Append(304, "Save", "", wx.ITEM_NORMAL)
587 FredericG 296
        self.frame_1_menubar.Append(wxglade_tmp_menu, "TestSet")
297
        wxglade_tmp_menu = wx.Menu()
626 FredericG 298
        wxglade_tmp_menu.Append(401, "Flash VibTest FC software", "", wx.ITEM_NORMAL)
299
        wxglade_tmp_menu.Append(402, "Restore original FC software", "", wx.ITEM_NORMAL)
587 FredericG 300
        self.frame_1_menubar.Append(wxglade_tmp_menu, "MK")
301
        wxglade_tmp_menu = wx.Menu()
626 FredericG 302
        wxglade_tmp_menu.Append(1099, "About", "", wx.ITEM_NORMAL)
587 FredericG 303
        self.frame_1_menubar.Append(wxglade_tmp_menu, "Help")
304
        self.SetMenuBar(self.frame_1_menubar)
305
        # Menu Bar end
633 FredericG 306
        self.label_1 = wx.StaticText(self, -1, "Test Description :", style=wx.ALIGN_RIGHT)
307
        self.descrCtrl = wx.TextCtrl(self, -1, "N/A")
308
        self.label_2 = wx.StaticText(self, -1, "Channel(s) :", style=wx.ALIGN_RIGHT)
309
        self.accTopCb = wx.CheckBox(self, -1, "ACC Top")
310
        self.accRollCb = wx.CheckBox(self, -1, "ACC Roll")
311
        self.accNickCb = wx.CheckBox(self, -1, "ACC Nick")
312
        self.label_3 = wx.StaticText(self, -1, "Motor(s) :", style=wx.ALIGN_RIGHT)
313
        self.motorsCtrl = wx.TextCtrl(self, -1, "1")
314
        self.label_4 = wx.StaticText(self, -1, "Speed(s) :")
315
        self.speedCtrl = wx.TextCtrl(self, -1, "100-200:10")
316
        self.bitmap_button_1 = wx.BitmapButton(self, -1, wx.Bitmap("Resources\\Fairytale_player_play.png", wx.BITMAP_TYPE_ANY))
317
        self.static_line_1 = wx.StaticLine(self, -1)
626 FredericG 318
        self.graphCtrl = wx.lib.plot.PlotCanvas(self, size=(800,300))
600 FredericG 319
        self.label_40 = wx.StaticText(self, -1, "Graph Type ")
320
        self.graphTypeChoice = wx.Choice(self, -1, choices=["Raw Signal", "Filtered Signal", "Spectrum"])
321
        self.label_41 = wx.StaticText(self, -1, "Y Axis Range ")
322
        self.yAxisChoice = wx.Choice(self, -1, choices=["25", "50", "100", "200"])
627 FredericG 323
        self.copyGraphButton = wx.Button(self, -1, "Copy Graph Data")
586 FredericG 324
        self.TestListCtrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
584 FredericG 325
 
326
        self.__set_properties()
327
        self.__do_layout()
587 FredericG 328
 
607 FredericG 329
        self.Bind(wx.EVT_MENU, self.OnSettings, id=101)
626 FredericG 330
        self.Bind(wx.EVT_MENU, self.onExit, id=150)
607 FredericG 331
        self.Bind(wx.EVT_MENU, self.onClear, id=301)
616 FredericG 332
        self.Bind(wx.EVT_MENU, self.onClearSelected, id=302)
627 FredericG 333
        self.Bind(wx.EVT_MENU, self.onSelectAll, id=310)
616 FredericG 334
        self.Bind(wx.EVT_MENU, self.OnImport, id=303)
335
        self.Bind(wx.EVT_MENU, self.onExport, id=304)
626 FredericG 336
        self.Bind(wx.EVT_MENU, self.onAbout, id=1099)
633 FredericG 337
        self.Bind(wx.EVT_BUTTON, self.onStartMeasure, self.bitmap_button_1)
600 FredericG 338
        self.Bind(wx.EVT_CHOICE, self.onGraphTypeChange, self.graphTypeChoice)
339
        self.Bind(wx.EVT_CHOICE, self.onYAxisChange, self.yAxisChoice)
627 FredericG 340
        self.Bind(wx.EVT_BUTTON, self.onCopyGraphData, self.copyGraphButton)
584 FredericG 341
        # end wxGlade
626 FredericG 342
        favicon = wx.Icon('%s/Resources/60px-Procman.ico' % rootPath, wx.BITMAP_TYPE_ICO, 32, 32)
343
        wx.Frame.SetIcon(self, favicon)
633 FredericG 344
 
584 FredericG 345
 
587 FredericG 346
    def setApp(self, app):
347
        self.app = app
585 FredericG 348
 
584 FredericG 349
    def __set_properties(self):
350
        # begin wxGlade: MainFrame.__set_properties
587 FredericG 351
        self.SetTitle("VibrationTest")
600 FredericG 352
        self.SetSize((850, 700))
633 FredericG 353
        self.label_1.SetMinSize((110, -1))
354
        self.label_1.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
355
        self.descrCtrl.SetMinSize((350, -1))
356
        self.label_2.SetMinSize((110, -1))
357
        self.label_2.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
358
        self.accTopCb.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
359
        self.accRollCb.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
360
        self.accRollCb.SetValue(1)
361
        self.accNickCb.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
362
        self.label_3.SetMinSize((110, -1))
363
        self.label_3.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
364
        self.label_4.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
365
        self.speedCtrl.SetToolTipString("e.g. \n 100 \n 100,150 \n 100-200:10")
366
        self.bitmap_button_1.SetToolTipString("Start Measurement")
367
        self.bitmap_button_1.SetSize(self.bitmap_button_1.GetBestSize())
368
        self.static_line_1.SetMinSize((800,3))
626 FredericG 369
        self.graphCtrl.SetMinSize((800,300))
633 FredericG 370
        self.label_40.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
600 FredericG 371
        self.graphTypeChoice.SetSelection(0)
633 FredericG 372
        self.label_41.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
600 FredericG 373
        self.yAxisChoice.SetSelection(1)
633 FredericG 374
        self.copyGraphButton.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
600 FredericG 375
        self.TestListCtrl.SetMinSize((800,300))
633 FredericG 376
        self.TestListCtrl.SetFont(wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
584 FredericG 377
        # end wxGlade
378
 
379
    def __do_layout(self):
380
        # begin wxGlade: MainFrame.__do_layout
600 FredericG 381
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
382
        sizer_8 = wx.BoxSizer(wx.VERTICAL)
383
        sizer_11 = wx.BoxSizer(wx.VERTICAL)
384
        sizer_12 = wx.BoxSizer(wx.HORIZONTAL)
633 FredericG 385
        sizer_17 = wx.BoxSizer(wx.VERTICAL)
600 FredericG 386
        sizer_9 = wx.BoxSizer(wx.HORIZONTAL)
633 FredericG 387
        sizer_7 = wx.BoxSizer(wx.HORIZONTAL)
388
        sizer_13 = wx.BoxSizer(wx.VERTICAL)
389
        sizer_16 = wx.BoxSizer(wx.HORIZONTAL)
390
        sizer_15 = wx.BoxSizer(wx.HORIZONTAL)
391
        sizer_14 = wx.BoxSizer(wx.HORIZONTAL)
600 FredericG 392
        sizer_3.Add((20, 20), 0, 0, 0)
393
        sizer_8.Add((20, 20), 0, 0, 0)
633 FredericG 394
        sizer_14.Add(self.label_1, 0, wx.ALIGN_CENTER_VERTICAL, 0)
395
        sizer_14.Add((20, 20), 0, 0, 0)
396
        sizer_14.Add(self.descrCtrl, 0, wx.ALIGN_CENTER_VERTICAL, 0)
397
        sizer_13.Add(sizer_14, 1, wx.EXPAND, 0)
398
        sizer_13.Add((20, 5), 0, 0, 0)
399
        sizer_15.Add(self.label_2, 0, wx.ALIGN_CENTER_VERTICAL, 0)
400
        sizer_15.Add((20, 20), 0, 0, 0)
401
        sizer_15.Add(self.accTopCb, 0, wx.ALIGN_CENTER_VERTICAL, 0)
402
        sizer_15.Add((20, 20), 0, 0, 0)
403
        sizer_15.Add(self.accRollCb, 0, wx.ALIGN_CENTER_VERTICAL, 0)
404
        sizer_15.Add((20, 20), 0, 0, 0)
405
        sizer_15.Add(self.accNickCb, 0, wx.ALIGN_CENTER_VERTICAL, 0)
406
        sizer_13.Add(sizer_15, 1, wx.EXPAND, 0)
407
        sizer_13.Add((20, 5), 0, 0, 0)
408
        sizer_16.Add(self.label_3, 0, wx.ALIGN_CENTER_VERTICAL, 0)
409
        sizer_16.Add((20, 20), 0, 0, 0)
410
        sizer_16.Add(self.motorsCtrl, 0, wx.ALIGN_CENTER_VERTICAL, 0)
411
        sizer_16.Add((50, 20), 0, 0, 0)
412
        sizer_16.Add(self.label_4, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 0)
413
        sizer_16.Add((20, 20), 0, 0, 0)
414
        sizer_16.Add(self.speedCtrl, 0, wx.ALIGN_CENTER_VERTICAL, 0)
415
        sizer_13.Add(sizer_16, 1, wx.EXPAND, 0)
416
        sizer_7.Add(sizer_13, 1, wx.EXPAND, 0)
417
        sizer_7.Add((20, 20), 0, 0, 0)
418
        sizer_7.Add((20, 20), 0, 0, 0)
419
        sizer_9.Add(sizer_7, 1, wx.EXPAND, 0)
420
        sizer_9.Add(self.bitmap_button_1, 0, 0, 0)
600 FredericG 421
        sizer_8.Add(sizer_9, 0, 0, 0)
633 FredericG 422
        sizer_17.Add((20, 20), 0, 0, 0)
423
        sizer_17.Add(self.static_line_1, 0, wx.EXPAND, 0)
424
        sizer_17.Add((20, 20), 0, 0, 0)
425
        sizer_8.Add(sizer_17, 0, wx.EXPAND, 0)
626 FredericG 426
        sizer_11.Add(self.graphCtrl, 1, wx.EXPAND, 0)
600 FredericG 427
        sizer_11.Add((20, 5), 0, 0, 0)
428
        sizer_12.Add(self.label_40, 0, wx.ALIGN_CENTER_VERTICAL, 0)
429
        sizer_12.Add(self.graphTypeChoice, 0, 0, 0)
430
        sizer_12.Add((40, 20), 0, 0, 0)
431
        sizer_12.Add(self.label_41, 0, wx.ALIGN_CENTER_VERTICAL, 0)
432
        sizer_12.Add(self.yAxisChoice, 0, 0, 0)
627 FredericG 433
        sizer_12.Add((80, 20), 0, 0, 0)
434
        sizer_12.Add(self.copyGraphButton, 0, 0, 0)
600 FredericG 435
        sizer_11.Add(sizer_12, 0, 0, 0)
436
        sizer_8.Add(sizer_11, 0, 0, 0)
437
        sizer_8.Add((20, 30), 0, 0, 0)
438
        sizer_8.Add(self.TestListCtrl, 1, 0, 0)
439
        sizer_8.Add((20, 20), 0, 0, 0)
440
        sizer_3.Add(sizer_8, 1, wx.EXPAND, 0)
441
        self.SetSizer(sizer_3)
584 FredericG 442
        self.Layout()
600 FredericG 443
        self.SetSize((850, 700))
584 FredericG 444
        # end wxGlade
445
 
590 FredericG 446
        # List events
447
        self.TestListCtrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTestSelected, self.TestListCtrl)
448
 
586 FredericG 449
        # Configure Graph
626 FredericG 450
        #self.graphCtrl = wx.lib.plot.PlotCanvas(self.GraphPanel, size=(800,300))
593 FredericG 451
 
626 FredericG 452
        self.graphCtrl.SetPointLabelFunc(self.DrawPointLabel)
585 FredericG 453
 
626 FredericG 454
        self.graphCtrl.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL))
455
        self.graphCtrl.SetFontSizeAxis(10)
456
        self.graphCtrl.SetFontSizeLegend(7)
457
        self.graphCtrl.setLogScale((False,False))
585 FredericG 458
 
586 FredericG 459
 
460
        # Configure TestListCtrl
594 FredericG 461
        self.TestListCtrl.InsertColumn(0, "Description")
619 FredericG 462
        self.TestListCtrl.InsertColumn(1, "Voltage")
463
        self.TestListCtrl.InsertColumn(2, "Speed")
464
        self.TestListCtrl.InsertColumn(3, "Channel")
465
        self.TestListCtrl.InsertColumn(4, "Vibration Value")
466
        self.TestListCtrl.SetColumnWidth(4, 500)
586 FredericG 467
 
585 FredericG 468
    def DrawPointLabel(self, dc, mDataDict):
469
        """This is the fuction that defines how the pointLabels are plotted
470
            dc - DC that will be passed
471
            mDataDict - Dictionary of data that you want to use for the pointLabel
472
 
473
            As an example I have decided I want a box at the curve point
474
            with some text information about the curve plotted below.
475
            Any wxDC method can be used.
476
        """
477
        # ----------
478
        dc.SetPen(wx.Pen(wx.BLACK))
479
        dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) )
480
 
481
        sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point
482
        dc.DrawRectangle( sx-5,sy-5, 10, 10)  #10by10 square centered on point
483
        px,py = mDataDict["pointXY"]
484
        cNum = mDataDict["curveNum"]
485
        pntIn = mDataDict["pIndex"]
486
        legend = mDataDict["legend"]
487
        #make a string to display
488
        s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn)
489
        dc.DrawText(s, sx , sy+1)
490
        # -----------
491
 
596 FredericG 492
 
493
    def onNewTest(self, test):
494
        index = self.TestListCtrl.InsertStringItem(sys.maxint, test.descr)
619 FredericG 495
        self.TestListCtrl.SetStringItem(index, 1, "%.1f V" %test.voltage)
496
        self.TestListCtrl.SetStringItem(index, 2, str(test.speed))
497
        self.TestListCtrl.SetStringItem(index, 3, test.channel)
607 FredericG 498
 
615 FredericG 499
        vv = int(test.getVibValue(self.app.settings["hpf"].value, self.app.settings["lpf"].value))
633 FredericG 500
        vvs = "|%s| (%d)" % ("----------------------------------------------------------------------------------------------------"[0:min(vv/2,100)], vv)
619 FredericG 501
        self.TestListCtrl.SetStringItem(index, 4, vvs)
613 FredericG 502
        self.TestListCtrl.Select(index)
596 FredericG 503
 
504
 
590 FredericG 505
    def OnTestSelected(self, event):
506
         testId = event.m_itemIndex
507
         print "Test Selected id=%d" % (testId)
592 FredericG 508
         self.activeTestId = testId
509
         self.drawGraph()
590 FredericG 510
 
592 FredericG 511
    def drawGraph(self):
607 FredericG 512
 
600 FredericG 513
         y = int(self.yAxisChoice.GetStringSelection())
590 FredericG 514
 
607 FredericG 515
         nbSelected = self.TestListCtrl.SelectedItemCount
596 FredericG 516
 
616 FredericG 517
         if nbSelected == 0:
626 FredericG 518
              self.graphCtrl.Clear()
616 FredericG 519
 
520
         elif nbSelected > 1:
607 FredericG 521
             self.graphTypeChoice.Disable()
627 FredericG 522
             self.copyGraphButton.Enable()
607 FredericG 523
             x = 1
524
             data = []
525
             idx = self.TestListCtrl.GetFirstSelected()
526
             while idx != -1:
615 FredericG 527
                 data.append([x,self.app.getTest(idx).getVibValue(self.app.settings["hpf"].value, self.app.settings["lpf"].value)])
607 FredericG 528
                 x += 1
529
                 idx = self.TestListCtrl.GetNextSelected(idx)
530
             line = wx.lib.plot.PolyLine(data, legend= 'Vibrations', colour='red', width=2)
531
             markers = wx.lib.plot.PolyMarker(data, legend= '', colour='red', marker='circle',size=2)
532
             title = "Comparing tests"
629 FredericG 533
             self.graphCtrl.setLogScale((False,False))
626 FredericG 534
             self.graphCtrl.Draw(wx.lib.plot.PlotGraphics([line, markers], title, "Test", "Vibration Value"), xAxis=(1,max(x,10)), yAxis=(0,y))
535
             self.graphCtrl.SetEnableGrid('Horizontal')
600 FredericG 536
 
607 FredericG 537
         else:
538
             self.graphTypeChoice.Enable()
627 FredericG 539
             self.copyGraphButton.Disable()
607 FredericG 540
             vibTest = self.app.getTest(self.activeTestId)
541
             nb = vibTest.getDataLen()
590 FredericG 542
 
607 FredericG 543
             if self.graphTypeChoice.GetSelection() == 0:
544
                 xydata = _Numeric.linspace(0,0.09*nb,2*nb)
545
                 xydata.shape = (nb, 2)
546
                 xydata[:,1] = vibTest.getRawData()
547
                 line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
548
 
549
                 title = "Raw Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
629 FredericG 550
                 self.graphCtrl.setLogScale((False,False))
626 FredericG 551
                 self.graphCtrl.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
552
                 self.graphCtrl.SetEnableGrid('Horizontal')
599 FredericG 553
 
607 FredericG 554
             if self.graphTypeChoice.GetSelection() == 1:
555
                 xydata = _Numeric.linspace(0,0.09*nb,2*nb)
556
                 xydata.shape = (nb, 2)
615 FredericG 557
                 xydata[:,1] = vibTest.getFilteredData(self.app.settings["hpf"].value, self.app.settings["lpf"].value)
607 FredericG 558
                 line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2)
559
 
560
                 title = "Filtered Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
629 FredericG 561
                 self.graphCtrl.setLogScale((False,False))
626 FredericG 562
                 self.graphCtrl.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y))
563
                 self.graphCtrl.SetEnableGrid('Horizontal')
607 FredericG 564
 
565
             elif self.graphTypeChoice.GetSelection() == 2:
615 FredericG 566
                 xydata = _Numeric.linspace(0,FS/2,nb)
607 FredericG 567
                 xydata.shape = (nb/2, 2)
568
 
569
                 xydata[:,1] = vibTest.getSpectrum()
629 FredericG 570
 
571
                 #print xydata
607 FredericG 572
 
573
                 line = wx.lib.plot.PolyLine(xydata, legend= 'Spectrum', colour='red')
574
                 markers = wx.lib.plot.PolyMarker(xydata, legend= '', colour='red', marker='circle',size=2)
615 FredericG 575
 
576
                 fc = self.app.settings["hpf"].value
577
                 filterLine1 = wx.lib.plot.PolyLine(((fc,0),(fc,y)), legend='HP Filter', colour='Black', width=4)
578
                 fc = self.app.settings["lpf"].value
579
                 filterLine2 = wx.lib.plot.PolyLine(((fc,0),(fc,y)), legend='HP Filter', colour='Black', width=4)
607 FredericG 580
 
581
                 title = "Spectrum: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed)
626 FredericG 582
                 self.graphCtrl.SetEnableGrid(True)
632 FredericG 583
                 self.graphCtrl.setLogScale((True,False))
584
                 self.graphCtrl.Draw(wx.lib.plot.PlotGraphics([line,markers, filterLine1, filterLine2], title, "Freq (Hz)", "Acc"), xAxis=(20,500), yAxis= (0,y))
629 FredericG 585
 
590 FredericG 586
 
599 FredericG 587
 
587 FredericG 588
    def OnImport(self, event): # wxGlade: MainFrame.<event_handler>
606 FredericG 589
        dlg = wx.FileDialog(
590
            self, message="Choose a file",
619 FredericG 591
            defaultDir="%s/Data/" % os.getcwd(),
606 FredericG 592
            defaultFile="*.txt",
619 FredericG 593
            wildcard="*.txt",
606 FredericG 594
            style=wx.OPEN | wx.CHANGE_DIR
595
            )
596
        if dlg.ShowModal() == wx.ID_OK:
597
            paths = dlg.GetPaths();
619 FredericG 598
            self.app.loadTests(paths[0])
606 FredericG 599
        dlg.Destroy()
587 FredericG 600
 
619 FredericG 601
    def onExport(self, event): # wxGlade: MainFrame.<event_handler>
602
        dlg = wx.FileDialog(
603
              self, message="Save file as ...",
604
              defaultDir="%s/Data/" % os.getcwd(),
605
              defaultFile="*.txt",
606
              wildcard="",
607
              style=wx.SAVE
608
              )
609
        if dlg.ShowModal() == wx.ID_OK:
610
            paths = dlg.GetPaths();
611
            self.app.saveTests(paths[0])
612
        dlg.Destroy()
613
 
599 FredericG 614
    def onYAxisChange(self, event): # wxGlade: MainFrame.<event_handler>
592 FredericG 615
        self.drawGraph()
616
 
600 FredericG 617
    def onGraphTypeChange(self, event): # wxGlade: MainFrame.<event_handler>
599 FredericG 618
        self.drawGraph()
619
 
607 FredericG 620
    def OnSettings(self, event): # wxGlade: MainFrame.<event_handler>
621
        dlg = SettingsDialog(self, -1, "Sample Dialog", size=(350, 200),
622
                         #style=wx.CAPTION | wx.SYSTEM_MENU | wx.THICK_FRAME,
623
                         style=wx.DEFAULT_DIALOG_STYLE, # & ~wx.CLOSE_BOX
624
                         )
625
        dlg.CenterOnScreen()
611 FredericG 626
        val = dlg.ShowModal()  # this does not return until the dialog is closed.
607 FredericG 627
        dlg.Destroy()
611 FredericG 628
        self.app.onSettingsChanged()
607 FredericG 629
 
612 FredericG 630
    def onStartMeasure(self, event): # wxGlade: MainFrame.<event_handler>
613 FredericG 631
        # Collect measure parameters
632
        mp = MeasureParameters()
633 FredericG 633
        mp.descr = self.descrCtrl.GetValue()
634
        mp.motors = map(int,self.motorsCtrl.GetValue().split(','))
635
        mp.channels = []
636
        if self.accTopCb.IsChecked(): mp.channels.append(5)
637
        if self.accRollCb.IsChecked(): mp.channels.append(6)
638
        if self.accNickCb.IsChecked(): mp.channels.append(7)
639
        s = self.speedCtrl.GetValue()
619 FredericG 640
        if s=="test":
641
          mp.speeds = (100,100,100,100,100, 150,150,150,150,150, 200,200,200,200,200, 100,150,200, 100,150,200, 100,150,200, 100,150,200)
642
        elif s.count("-") == 1:
613 FredericG 643
            # assume from-to:step format
644
            s = s.split("-")
645
            if len(s) != 2: raise Exception("Invalid format")
646
            s[1] = s[1].split(":")
647
            if len(s[1]) != 2: raise Exception("Invalid format")
648
            mp.speeds = range(int(s[0]),int(s[1][0])+int(s[1][1]),int(s[1][1]))
649
        else:
614 FredericG 650
            mp.speeds = map(int,s.split(','))
651
 
633 FredericG 652
        print mp.descr
653
        print mp.motors
654
        print mp.channels
655
        print mp.speeds
613 FredericG 656
 
633 FredericG 657
 
658
 
612 FredericG 659
        # create the dialog that will show the satus
660
        dlg = MeasureDialog(self)
661
        dlg.CenterOnScreen()
613 FredericG 662
 
663
        # Signal the application
664
        self.app.startMeasure(mp, dlg)
665
 
612 FredericG 666
        # Show the dialog
667
        val = dlg.ShowModal()  # this does not return until the dialog is closed.
668
        dlg.Destroy()
669
 
616 FredericG 670
    def _removeTest(self, idx):
671
        print "Deleting test %d" % idx
672
        self.app.removeTest(idx)
673
        self.TestListCtrl.DeleteItem(idx)
674
 
675
 
676
    def onClear(self, event): # wxGlade: MainFrame.<event_handler>
677
        print "Clear all tests"
678
        for i in range(len(self.app.VibTests)-1, -1, -1):
679
            self._removeTest(i)
680
        self.drawGraph()
681
 
682
 
683
    def onClearSelected(self, event): # wxGlade: MainFrame.<event_handler>
684
        while True:
685
            idx = self.TestListCtrl.GetFirstSelected()
686
            if idx == -1: break
687
            self._removeTest(idx)
688
 
627 FredericG 689
 
626 FredericG 690
 
691
    def onAbout(self, event): # wxGlade: MainFrame.<event_handler>
692
         # First we create and fill the info object
693
        print "about"
694
        info = wx.AboutDialogInfo()
695
        info.Name = "MK Vibration Test"
696
        info.Version = "0.2"
697
        info.Copyright = ""
698
        info.Developers=["Frederic Goddeeris"]
699
        info.Description = "Please consult the WIKI page for a complete description of the tool:"
700
        info.WebSite = ("http://www.mikrokopter.de/ucwiki/en/VibrationTest", "VibrationTest WIKI page")
701
        wx.AboutBox(info)
702
 
703
 
704
    def onExit(self, event): # wxGlade: MainFrame.<event_handler>
705
        self.Close(True)
706
 
707
 
627 FredericG 708
    def onSelectAll(self, event): # wxGlade: MainFrame.<event_handler>
709
        for i in xrange(self.TestListCtrl.GetItemCount()):
710
          self.TestListCtrl.Select(i)
711
 
712
    def onCopyGraphData(self, event): # wxGlade: MainFrame.<event_handler>
713
        clipdata = wx.TextDataObject()
714
        txt = ""
715
        idx = self.TestListCtrl.GetFirstSelected()
716
        while idx != -1:
717
             txt += ("%d\n" % self.app.getTest(idx).getVibValue(self.app.settings["hpf"].value, self.app.settings["lpf"].value))
718
             idx = self.TestListCtrl.GetNextSelected(idx)
719
        clipdata.SetText(txt)
720
        wx.TheClipboard.Open()
721
        wx.TheClipboard.SetData(clipdata)
722
        wx.TheClipboard.Close()
723
 
584 FredericG 724
# end of class MainFrame
725
 
607 FredericG 726
class Setting:
727
    def __init__(self, descr, defaultValue):
728
        self.descr = descr
729
        self.value = defaultValue
611 FredericG 730
 
731
    def set(self, newValue):
732
        if isinstance(self.value, int):
733
            self.value = int(newValue)
734
        else:
735
            self.value = str(newValue)
584 FredericG 736
 
613 FredericG 737
class MeasureParameters:
738
      pass
612 FredericG 739
 
740
class MeasureThread:
613 FredericG 741
    def __init__(self, measureParameters, evtConsumer):
742
        self.mk = mkProto.MkComm()
743
        self.param = measureParameters
612 FredericG 744
        self.evtConsumer = evtConsumer
613 FredericG 745
        self.cancel = False
746
        self.running = False
612 FredericG 747
 
748
    def start(self):
749
        thread.start_new_thread(self._run, ())
750
 
613 FredericG 751
    def stop(self):
752
        self.cancel = True
753
 
754
    def _testCancel(self):
755
        if self.cancel:
756
            raise Exception("Operation cancelled")
757
 
623 FredericG 758
    def _sendEvent(self, msg=None, error=False, parVoltage=None, speed=None):
759
        evt = MeasStatusUpdateEvent(running=self.running, msg=msg, error=error, voltage=parVoltage, speed=speed)
613 FredericG 760
        wx.PostEvent(self.evtConsumer, evt)
761
 
762
    def _setMotorSpeed(self, speed, settlingTime):
763
        speeds = [0,0,0,0]
764
        for motor in self.param.motors:
765
            speeds[motor-1] = speed
766
        for i in range(int(settlingTime*10)):
767
          self._testCancel()
768
          self.mk.setMotorTest(speeds)
769
          time.sleep(.1)
770
 
771
 
612 FredericG 772
    def _run(self):
613 FredericG 773
        self.running = True
774
        self._sendEvent("Starting test \"%s\"" % self.param.descr)    
775
 
776
        try:
777
            self._sendEvent("Opening SerialPort \"%s\"" % self.param.serialPort)
778
            self.mk.open(comPort=self.param.serialPort)
612 FredericG 779
 
613 FredericG 780
            msg = self.mk.getVersionMsg()
781
            version = msg.getVersion()
782
            self._sendEvent("Version: %d.%d" % version)
783
 
784
            msg = self.mk.getDebugMsg()
785
            voltage = msg.getVoltage()
786
            if (voltage == 0):
628 FredericG 787
              # Board is probably fed by USB
613 FredericG 788
              minVoltage = 0
623 FredericG 789
              maxVoltage = 1
613 FredericG 790
            else:
628 FredericG 791
              # Determine the n umber of cells
613 FredericG 792
              if (voltage > 4.2*3):
623 FredericG 793
                nbCells = 4  
613 FredericG 794
              else:
623 FredericG 795
                nbCells = 3
628 FredericG 796
              # Set minimum and maximum voltages
797
              if self.param.minVoltage > 0:
798
                minVoltage =  self.param.minVoltage
799
              else:
800
                minVoltage = nbCells*3.5  # auto
801
              if self.param.maxVoltage > 0:
802
                maxVoltage =  self.param.maxVoltage
803
              else:
804
                maxVoltage = nbCells*3.9  
805
 
613 FredericG 806
            self._sendEvent("Voltage: %2.1fV" % voltage)
623 FredericG 807
            self._sendEvent("Min/Max Voltage: %2.1fV-%2.1fV" % (minVoltage, maxVoltage), parVoltage=(minVoltage, maxVoltage, voltage))
808
 
809
            self._sendEvent("Starting motor(s) (speed=%d)... " % self.param.motorStartupSpeed, speed=self.param.motorStartupSpeed)
613 FredericG 810
            self._setMotorSpeed(self.param.motorStartupSpeed, self.param.motorStartupSettlingTime)
811
 
812
            for speed in self.param.speeds:
623 FredericG 813
                self._sendEvent("Changing motor speed to %d... " % speed, speed=speed)
613 FredericG 814
                self._setMotorSpeed(speed, 1)
815
 
816
                for channel in self.param.channels:
817
                    self._setMotorSpeed(speed, .1)
619 FredericG 818
                    msg = self.mk.getDebugMsg()
819
                    voltage = msg.getVoltage()
820
 
623 FredericG 821
                    self._sendEvent("Getting data from channel %s" % CHANNEL_NAMES[channel], parVoltage=(minVoltage, maxVoltage, voltage))
613 FredericG 822
                    data = self.mk.doVibrationTest(1000, channel)
823
 
619 FredericG 824
                    vt = VibTest(self.param.descr, voltage, self.param.motors, speed, CHANNEL_NAMES[channel], data)
613 FredericG 825
                    evt = MeasDataEvent(vibTest = vt)
826
                    wx.PostEvent(self.evtConsumer, evt)
827
 
619 FredericG 828
                    if voltage<minVoltage:
829
                        raise Exception("Voltage too low")
830
 
613 FredericG 831
            self._sendEvent("Done !")            
629 FredericG 832
            self._setMotorSpeed(speed, .1)
612 FredericG 833
 
613 FredericG 834
        except Exception, e:
835
            self._sendEvent("Exception \"%s\"" % e, error=True)  
836
 
837
        self.running = False
629 FredericG 838
        self._sendEvent("", speed = 0)    
613 FredericG 839
 
612 FredericG 840
 
586 FredericG 841
class VibTest:
619 FredericG 842
    def __init__(self, descr, voltage, motor, speed, channel, rawData):
594 FredericG 843
        self.descr = descr
619 FredericG 844
        self.voltage = voltage
594 FredericG 845
        self.motor = motor
846
        self.speed = speed
596 FredericG 847
        self.channel = channel
599 FredericG 848
 
849
        self.dataLen = len(rawData)
850
 
590 FredericG 851
        self.rawData = _Numeric.array(rawData)
852
        self.dc = self.rawData.mean()
853
        self.rawData -= self.dc
586 FredericG 854
 
600 FredericG 855
        self.fft = _Numeric.fft.rfft(self.rawData)
856
 
857
        self.spectrum = None
858
        self.filteredData = None
615 FredericG 859
        self.fc1 = None
860
        self.fc2 = None
599 FredericG 861
 
602 FredericG 862
        self.vibValue = None
863
 
594 FredericG 864
    def getDescr(self):
865
        return self.Descr
587 FredericG 866
 
590 FredericG 867
    def getRawData(self):
868
        return self.rawData
869
 
870
    def getDataLen(self):
871
        return self.dataLen
872
 
599 FredericG 873
    def getSpectrum(self):
600 FredericG 874
        if self.spectrum == None:
875
            self.spectrum = _Numeric.absolute(self.fft[1:self.dataLen/2+1]) / (self.dataLen/2)
876
        return self.spectrum
590 FredericG 877
 
615 FredericG 878
    def getFilteredData(self, fc1, fc2):
879
        if self.fc1 != fc1 or self.fc2 != fc2:
880
            self.filteredData = None  
881
 
600 FredericG 882
        if self.filteredData == None:
883
            tmpfft = self.fft.copy()
615 FredericG 884
            fc = (float(fc1))/(FS/2)*len(tmpfft)
885
            print "fc1=%d => fc=%d" % (fc1,fc)
886
            for i in range(0,int(fc)):
600 FredericG 887
                tmpfft[i] = 0
615 FredericG 888
            fc = (float(fc2))/(FS/2)*len(tmpfft)
889
            print "fc2=%d => fc=%d" % (fc2,fc)
890
            for i in range(int(fc), len(tmpfft)):
600 FredericG 891
                tmpfft[i] = 0
892
            self.filteredData = _Numeric.fft.irfft(tmpfft)
615 FredericG 893
            self.fc1 = fc1
894
            self.fc2 = fc2
895
 
600 FredericG 896
        return self.filteredData
602 FredericG 897
 
615 FredericG 898
    def getVibValue(self, fc1, fc2):
899
      if self.fc1 != fc1 or self.fc2 != fc2:
900
        self.vibValue = None  
602 FredericG 901
      if self.vibValue == None:
615 FredericG 902
        fd = self.getFilteredData(fc1, fc2)[100:-100];
602 FredericG 903
        self.vibValue = max(fd)-min(fd)
904
      return self.vibValue
599 FredericG 905
 
607 FredericG 906
 
907
 
584 FredericG 908
class App(wx.App):
607 FredericG 909
 
910
    SETTINGSFILE = "settings.cfg"
911
 
586 FredericG 912
    def __init__(self, par):
913
        self.VibTests = []
914
        wx.App.__init__(self, par)
915
 
607 FredericG 916
        # Init settings
917
        self.settings={}
611 FredericG 918
        self.settings["serialport"] = Setting("Serial Port", "COM1")
613 FredericG 919
        self.settings["startupspeed"] = Setting("Motor Startup Speed", 25)
920
        self.settings["startupsettling"] = Setting("Motor Startup Setting time (s)", 3)
921
        self.settings["serialport"] = Setting("Serial Port", "COM1")
607 FredericG 922
        self.settings["hpf"] = Setting("HP Filter cutoff (Hz)", 50)
632 FredericG 923
        self.settings["lpf"] = Setting("LP Filter cutoff (Hz)", 400)
628 FredericG 924
        self.settings["minvoltage"] = Setting("Minimum Bettery Voltage (0=Automatic) (V) ", 0)
925
        self.settings["maxvoltage"] = Setting("Maximum Bettery Voltage (0=Automatic) (V) ", 0)
607 FredericG 926
 
628 FredericG 927
 
607 FredericG 928
        self.readSettings()
929
 
606 FredericG 930
        if len(sys.argv)>1:
619 FredericG 931
            self.loadTests(sys.argv[1])
586 FredericG 932
 
606 FredericG 933
 
607 FredericG 934
    def readSettings(self):
935
        print "Reading settings"
936
        cp = ConfigParser.ConfigParser()
937
 
938
        try:
939
            cp.read(App.SETTINGSFILE)
940
            for setting in cp.items("DEFAULT"):
941
                print " ",setting
942
                try:
613 FredericG 943
                    self.settings[setting[0]].set(setting[1])
607 FredericG 944
                except:
945
                    print "WARNING, unknown setting"
946
        except:
947
            print "ERROR reading settingsfile"
948
 
949
 
950
    def storeSettings(self):
951
        print "Storing settings"
952
 
953
        cp = ConfigParser.ConfigParser()
954
        for setting in self.settings.iteritems():
955
            cp.set("", setting[0], setting[1].value)
956
 
957
        file = open(App.SETTINGSFILE, "w")
958
        cp.write(file)
959
        file.close()
960
 
611 FredericG 961
 
962
    def onSettingsChanged(self):
963
        self.storeSettings()
613 FredericG 964
 
965
    def AddTest2(self, vibTest):
966
        self.VibTests.append(vibTest)
967
        self.frame_1.onNewTest(vibTest)
611 FredericG 968
 
619 FredericG 969
    def AddTest(self, descr, voltage, motor, speed, channel, rawData):
970
        test = VibTest(descr, voltage, motor, speed, channel, rawData)
613 FredericG 971
        self.AddTest2(test)
586 FredericG 972
 
616 FredericG 973
    def removeTest(self, idx):
974
        del(self.VibTests[idx])
975
 
590 FredericG 976
    def getTest(self, testId):
977
        return self.VibTests[testId]
978
 
584 FredericG 979
    def OnInit(self):
980
        wx.InitAllImageHandlers()
586 FredericG 981
        self.frame_1 = MainFrame(None, -1, "")
587 FredericG 982
        self.frame_1.setApp(self);
586 FredericG 983
        self.SetTopWindow(self.frame_1)
984
 
607 FredericG 985
        self.frame_1.CenterOnScreen()
587 FredericG 986
        self.frame_1.Show()
987
        return 1
988
 
619 FredericG 989
    def saveTests(self, filePath):
990
        try:
991
          logfile = open(filePath, "r")
992
          newFile = False
993
          logfile.close()
994
        except:
995
          newFile = True
996
 
997
        for test in self.VibTests:
998
          if newFile:
999
            logfile = open(filePath, "w")
1000
            print "Writing result to %s ..." % filePath,
1001
            logfile.write("%s %d %s\n" % (test.descr, test.speed, test.channel))
1002
            for value in test.rawData:
1003
              logfile.write("%d\n" % value)
1004
            logfile.close()  
1005
            print "OK"
1006
          else:
1007
            print "Appending result to %s ..." % filePath,
1008
            logfile = open(filePath, "r")
1009
            prevData = []
1010
            for line in logfile:
1011
              prevData.append(line[:-1])
1012
            logfile.close()
1013
            logfile = open(filePath, "w")
1014
            logfile.write("%s,%s %d %s\n" % (prevData[0], test.descr, test.speed, test.channel))
1015
            i = 1
1016
            for value in test.rawData:
1017
              logfile.write("%s,%d\n" % (prevData[i], value))
1018
              i += 1
1019
            logfile.close()
1020
            print "OK"
1021
          newFile = False
1022
 
1023
 
1024
    def loadTests(self, filePath):
596 FredericG 1025
 
606 FredericG 1026
        print "Importing file \"%s\"" % filePath
596 FredericG 1027
 
1028
        logfile = open(filePath, "r")
590 FredericG 1029
        data = None
596 FredericG 1030
 
619 FredericG 1031
        headers = (logfile.readline()[:-1]).split(',')
596 FredericG 1032
        nbCols = len(headers)
1033
        print "NbCols =", nbCols
1034
 
1035
        data = []
1036
        descr = []
1037
        speed = []
1038
        channel = []
1039
        for c in range(nbCols):
1040
            data.append([])
1041
            h = headers[c].split(' ')
1042
            descr.append(h[0]);
1043
            speed.append(h[1]);
1044
            channel.append(h[2]);
1045
 
590 FredericG 1046
        for line in logfile:
1047
            values = line.split(',')
596 FredericG 1048
            for i in range(nbCols):
1049
                data[i].append(int(values[i]))
590 FredericG 1050
        logfile.close()
596 FredericG 1051
 
1052
        for c in range(nbCols):
599 FredericG 1053
            if (len(data[c]) % 2) != 0:
1054
                data[c].append(data[c][-1])
619 FredericG 1055
            self.AddTest(descr[c], 0, 0, int(speed[c]), channel[c], data[c])
612 FredericG 1056
 
613 FredericG 1057
    def startMeasure(self, measureParams, dialog):
612 FredericG 1058
        print "Start measuring"
590 FredericG 1059
 
613 FredericG 1060
        measureParams.serialPort = self.settings["serialport"].value
1061
        measureParams.motorStartupSpeed = self.settings["startupspeed"].value
1062
        measureParams.motorStartupSettlingTime = self.settings["startupsettling"].value
628 FredericG 1063
        measureParams.minVoltage = self.settings["minvoltage"].value
1064
        measureParams.maxVoltage = self.settings["maxvoltage"].value        
613 FredericG 1065
 
1066
        self.measureThread = MeasureThread(measureParams, dialog)
612 FredericG 1067
        self.measureThread.start()
590 FredericG 1068
 
613 FredericG 1069
    def cancelMeasurement(self):
1070
        print "Measuring CANCEL"
1071
 
1072
        self.measureThread.stop()
1073
 
612 FredericG 1074
 
1075
 
1076
 
1077
 
590 FredericG 1078
 
586 FredericG 1079
 
590 FredericG 1080
 
584 FredericG 1081
# end of class App
1082
 
1083
if __name__ == "__main__":
626 FredericG 1084
 
1085
    rootPath = os.path.abspath(os.path.dirname(sys.argv[0]))
1086
 
1087
    print rootPath
1088
 
584 FredericG 1089
    VibrationTestGui = App(0)
1090
    VibrationTestGui.MainLoop()