Subversion Repositories Projects

Rev

Rev 683 | Rev 692 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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