Subversion Repositories Projects

Rev

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