Subversion Repositories Projects

Rev

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