Subversion Repositories Projects

Rev

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