Subversion Repositories Projects

Rev

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