Subversion Repositories Projects

Rev

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