Subversion Repositories Projects

Rev

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