Rev 612 | Rev 614 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 612 | Rev 613 | ||
---|---|---|---|
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 | import sys |
5 | import sys |
6 | import os |
6 | import os |
7 | import time |
7 | import time |
8 | import thread |
8 | import thread |
9 | import ConfigParser |
9 | import ConfigParser |
10 | 10 | ||
11 | import wx |
11 | import wx |
12 | import wx.lib |
12 | import wx.lib |
13 | import wx.lib.plot |
13 | import wx.lib.plot |
14 | import wx.lib.newevent |
14 | import wx.lib.newevent |
- | 15 | ||
- | 16 | import mkProto |
|
- | 17 | ||
- | 18 | ||
- | 19 | ||
- | 20 | CHANNEL_NAMES = ["GyroYaw", "GyroRoll", "GyroNick", "Pressure", "Batt", "AccTop", "AccRoll", "AccNick"] |
|
15 | 21 | ||
16 | # Needs Numeric or numarray or NumPy |
22 | # Needs Numeric or numarray or NumPy |
17 | try: |
23 | try: |
18 | import numpy.oldnumeric as _Numeric |
24 | import numpy.oldnumeric as _Numeric |
19 | except: |
25 | except: |
20 | try: |
26 | try: |
21 | import numarray as _Numeric #if numarray is used it is renamed Numeric |
27 | import numarray as _Numeric #if numarray is used it is renamed Numeric |
22 | except: |
28 | except: |
23 | try: |
29 | try: |
24 | import Numeric as _Numeric |
30 | import Numeric as _Numeric |
25 | except: |
31 | except: |
26 | msg= """ |
32 | msg= """ |
27 | This module requires the Numeric/numarray or NumPy module, |
33 | This module requires the Numeric/numarray or NumPy module, |
28 | which could not be imported. It probably is not installed |
34 | which could not be imported. It probably is not installed |
29 | (it's not part of the standard Python distribution). See the |
35 | (it's not part of the standard Python distribution). See the |
30 | Numeric Python site (http://numpy.scipy.org) for information on |
36 | Numeric Python site (http://numpy.scipy.org) for information on |
31 | downloading source or binaries.""" |
37 | downloading source or binaries.""" |
32 | raise ImportError, "Numeric,numarray or NumPy not found. \n" + msg |
38 | raise ImportError, "Numeric,numarray or NumPy not found. \n" + msg |
33 | 39 | ||
34 | # begin wxGlade: extracode |
40 | # begin wxGlade: extracode |
35 | # end wxGlade |
41 | # end wxGlade |
36 | 42 | ||
37 | 43 | ||
38 | # This creates a new Event class and a EVT binder function |
44 | # This creates a new Event class and a EVT binder function |
39 | (MeasStatusUpdateEvent, EVT_MEAS_STATUS_UPDATE) = wx.lib.newevent.NewEvent() |
45 | (MeasStatusUpdateEvent, EVT_MEAS_STATUS_UPDATE) = wx.lib.newevent.NewEvent() |
- | 46 | (MeasDataEvent, EVT_MEAS_DATA) = wx.lib.newevent.NewEvent() |
|
40 | 47 | ||
41 | class MeasureDialog(wx.Dialog): |
48 | class MeasureDialog(wx.Dialog): |
42 | def __init__(self, *args, **kwds): |
49 | def __init__(self, *args, **kwds): |
43 | # begin wxGlade: MeasureDialog.__init__ |
50 | # begin wxGlade: MeasureDialog.__init__ |
44 | kwds["style"] = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.THICK_FRAME |
51 | kwds["style"] = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.THICK_FRAME |
45 | wx.Dialog.__init__(self, *args, **kwds) |
52 | wx.Dialog.__init__(self, *args, **kwds) |
46 | self.text_ctrl_1 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL) |
53 | self.text_ctrl_1 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL) |
47 | self.button = wx.Button(self, -1, "STOP") |
54 | self.button = wx.Button(self, -1, "STOP") |
48 | 55 | ||
49 | self.__set_properties() |
56 | self.__set_properties() |
50 | self.__do_layout() |
57 | self.__do_layout() |
51 | 58 | ||
52 | self.Bind(wx.EVT_BUTTON, self.onButton, self.button) |
59 | self.Bind(wx.EVT_BUTTON, self.onButton, self.button) |
53 | # end wxGlade |
60 | # end wxGlade |
54 | 61 | ||
55 | self.running = True |
62 | self.running = True |
56 | self.Bind(EVT_MEAS_STATUS_UPDATE, self.OnUpdate) |
63 | self.Bind(EVT_MEAS_STATUS_UPDATE, self.OnUpdate) |
- | 64 | self.Bind(EVT_MEAS_DATA, self.OnData) |
|
- | 65 | # The first argument that is passed to the constructor is the parent |
|
- | 66 | self.app = args[0].app |
|
- | 67 | self.error = False |
|
57 | 68 | ||
58 | def __set_properties(self): |
69 | def __set_properties(self): |
59 | # begin wxGlade: MeasureDialog.__set_properties |
70 | # begin wxGlade: MeasureDialog.__set_properties |
60 | self.SetTitle("Measuring Status") |
71 | self.SetTitle("Measuring Status") |
61 | self.text_ctrl_1.SetMinSize((400,300)) |
72 | self.text_ctrl_1.SetMinSize((400,300)) |
62 | # end wxGlade |
73 | # end wxGlade |
63 | 74 | ||
64 | def __do_layout(self): |
75 | def __do_layout(self): |
65 | # begin wxGlade: MeasureDialog.__do_layout |
76 | # begin wxGlade: MeasureDialog.__do_layout |
66 | sizer_1 = wx.BoxSizer(wx.HORIZONTAL) |
77 | sizer_1 = wx.BoxSizer(wx.HORIZONTAL) |
67 | sizer_2 = wx.BoxSizer(wx.VERTICAL) |
78 | sizer_2 = wx.BoxSizer(wx.VERTICAL) |
68 | sizer_1.Add((20, 20), 0, 0, 0) |
79 | sizer_1.Add((20, 20), 0, 0, 0) |
69 | sizer_2.Add((20, 20), 0, 0, 0) |
80 | sizer_2.Add((20, 20), 0, 0, 0) |
70 | sizer_2.Add(self.text_ctrl_1, 1, wx.EXPAND, 0) |
81 | sizer_2.Add(self.text_ctrl_1, 1, wx.EXPAND, 0) |
71 | sizer_2.Add((20, 20), 0, 0, 0) |
82 | sizer_2.Add((20, 20), 0, 0, 0) |
72 | sizer_2.Add(self.button, 0, wx.ALIGN_CENTER_HORIZONTAL, 0) |
83 | sizer_2.Add(self.button, 0, wx.ALIGN_CENTER_HORIZONTAL, 0) |
73 | sizer_2.Add((20, 20), 0, 0, 0) |
84 | sizer_2.Add((20, 20), 0, 0, 0) |
74 | sizer_1.Add(sizer_2, 1, wx.EXPAND, 0) |
85 | sizer_1.Add(sizer_2, 1, wx.EXPAND, 0) |
75 | sizer_1.Add((20, 20), 0, 0, 0) |
86 | sizer_1.Add((20, 20), 0, 0, 0) |
76 | self.SetSizer(sizer_1) |
87 | self.SetSizer(sizer_1) |
77 | sizer_1.Fit(self) |
88 | sizer_1.Fit(self) |
78 | self.Layout() |
89 | self.Layout() |
79 | # end wxGlade |
90 | # end wxGlade |
- | 91 | ||
- | 92 | def OnData(self, evt): |
|
- | 93 | print "Received Data" |
|
- | 94 | self.app.AddTest2(evt.vibTest) |
|
80 | 95 | ||
81 | def OnUpdate(self, evt): |
96 | def OnUpdate(self, evt): |
82 | print "Event received" |
97 | print "Status update" |
- | 98 | self.running = evt.running |
|
- | 99 | if evt.error: |
|
- | 100 | self.error = True; |
|
- | 101 | self.text_ctrl_1.WriteText("ERROR: ") |
|
83 | self.running = evt.running |
102 | self.text_ctrl_1.SetBackgroundColour("Red") |
84 | self.text_ctrl_1.WriteText("%s\n"%evt.msg) |
103 | self.text_ctrl_1.WriteText("%s\n"%evt.msg) |
- | 104 | if (not self.running): |
|
- | 105 | if (not self.error): |
|
- | 106 | self.text_ctrl_1.SetBackgroundColour("Green") |
|
85 | if (not self.running): |
107 | self.text_ctrl_1.write(" ") # so that the background is redrawn |
- | 108 | self.button.SetLabel("Close") |
|
86 | self.button.SetLabel("Close") |
109 | |
87 | 110 | ||
88 | def onButton(self, event): # wxGlade: MeasureDialog.<event_handler> |
111 | def onButton(self, event): # wxGlade: MeasureDialog.<event_handler> |
89 | if (not self.running): |
112 | if (not self.running): |
90 | self.Destroy() |
113 | self.Destroy() |
- | 114 | else: |
|
- | 115 | self.app.cancelMeasurement() |
|
91 | 116 | ||
92 | # end of class MeasureDialog |
117 | # end of class MeasureDialog |
93 | 118 | ||
94 | 119 | ||
95 | class SettingsDialog(wx.Dialog): |
120 | class SettingsDialog(wx.Dialog): |
96 | def __init__(self, *args, **kwds): |
121 | def __init__(self, *args, **kwds): |
97 | # begin wxGlade: SettingsDialog.__init__ |
122 | # begin wxGlade: SettingsDialog.__init__ |
98 | kwds["style"] = wx.DEFAULT_DIALOG_STYLE |
123 | kwds["style"] = wx.DEFAULT_DIALOG_STYLE |
99 | wx.Dialog.__init__(self, *args, **kwds) |
124 | wx.Dialog.__init__(self, *args, **kwds) |
100 | self.button_5 = wx.Button(self, wx.ID_CANCEL, "") |
125 | self.button_5 = wx.Button(self, wx.ID_CANCEL, "") |
101 | self.button_6 = wx.Button(self, wx.ID_OK, "") |
126 | self.button_6 = wx.Button(self, wx.ID_OK, "") |
102 | 127 | ||
103 | self.__set_properties() |
128 | self.__set_properties() |
104 | self.__do_layout() |
129 | self.__do_layout() |
105 | 130 | ||
106 | self.Bind(wx.EVT_BUTTON, self.onOK, self.button_6) |
131 | self.Bind(wx.EVT_BUTTON, self.onOK, self.button_6) |
107 | # end wxGlade |
132 | # end wxGlade |
108 | 133 | ||
109 | # The first argument that is passed to the constructor is the parent |
134 | # The first argument that is passed to the constructor is the parent |
110 | self.settings = args[0].app.settings |
135 | self.settings = args[0].app.settings |
111 | # Add text-boxes for all settings |
136 | # Add text-boxes for all settings |
112 | self.tb = [] |
137 | self.tb = [] |
113 | self.grid_sizer_2.SetRows(len(self.settings)) |
138 | self.grid_sizer_2.SetRows(len(self.settings)) |
114 | for setting in self.settings.iteritems(): |
139 | for setting in self.settings.iteritems(): |
115 | lb = wx.StaticText(self, -1, setting[1].descr, style=wx.ALIGN_RIGHT) |
140 | lb = wx.StaticText(self, -1, setting[1].descr, style=wx.ALIGN_RIGHT) |
116 | tb = wx.TextCtrl(self, -1, str(setting[1].value)) |
141 | tb = wx.TextCtrl(self, -1, str(setting[1].value)) |
117 | self.grid_sizer_2.Add(lb, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
142 | self.grid_sizer_2.Add(lb, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
118 | self.grid_sizer_2.Add(tb, 0, 0, 0) |
143 | self.grid_sizer_2.Add(tb, 0, 0, 0) |
119 | self.tb.append(tb) |
144 | self.tb.append(tb) |
120 | self.sizer_5.Fit(self) |
145 | self.sizer_5.Fit(self) |
121 | self.Layout() |
146 | self.Layout() |
122 | 147 | ||
123 | def __set_properties(self): |
148 | def __set_properties(self): |
124 | # begin wxGlade: SettingsDialog.__set_properties |
149 | # begin wxGlade: SettingsDialog.__set_properties |
125 | self.SetTitle("Settings") |
150 | self.SetTitle("Settings") |
126 | # end wxGlade |
151 | # end wxGlade |
127 | 152 | ||
128 | def __do_layout(self): |
153 | def __do_layout(self): |
129 | # begin wxGlade: SettingsDialog.__do_layout |
154 | # begin wxGlade: SettingsDialog.__do_layout |
130 | sizer_5 = wx.BoxSizer(wx.VERTICAL) |
155 | sizer_5 = wx.BoxSizer(wx.VERTICAL) |
131 | grid_sizer_3 = wx.GridSizer(1, 2, 0, 0) |
156 | grid_sizer_3 = wx.GridSizer(1, 2, 0, 0) |
132 | sizer_6 = wx.BoxSizer(wx.HORIZONTAL) |
157 | sizer_6 = wx.BoxSizer(wx.HORIZONTAL) |
133 | grid_sizer_2 = wx.GridSizer(1, 2, 4, 4) |
158 | grid_sizer_2 = wx.GridSizer(1, 2, 4, 4) |
134 | sizer_5.Add((20, 20), 0, 0, 0) |
159 | sizer_5.Add((20, 20), 0, 0, 0) |
135 | sizer_6.Add((20, 20), 0, 0, 0) |
160 | sizer_6.Add((20, 20), 0, 0, 0) |
136 | sizer_6.Add(grid_sizer_2, 0, 0, 0) |
161 | sizer_6.Add(grid_sizer_2, 0, 0, 0) |
137 | sizer_6.Add((20, 20), 0, 0, 0) |
162 | sizer_6.Add((20, 20), 0, 0, 0) |
138 | sizer_5.Add(sizer_6, 1, wx.EXPAND, 0) |
163 | sizer_5.Add(sizer_6, 1, wx.EXPAND, 0) |
139 | sizer_5.Add((20, 20), 0, 0, 0) |
164 | sizer_5.Add((20, 20), 0, 0, 0) |
140 | grid_sizer_3.Add(self.button_5, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0) |
165 | grid_sizer_3.Add(self.button_5, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0) |
141 | grid_sizer_3.Add(self.button_6, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0) |
166 | grid_sizer_3.Add(self.button_6, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0) |
142 | sizer_5.Add(grid_sizer_3, 0, wx.EXPAND, 0) |
167 | sizer_5.Add(grid_sizer_3, 0, wx.EXPAND, 0) |
143 | sizer_5.Add((20, 20), 0, 0, 0) |
168 | sizer_5.Add((20, 20), 0, 0, 0) |
144 | self.SetSizer(sizer_5) |
169 | self.SetSizer(sizer_5) |
145 | sizer_5.Fit(self) |
170 | sizer_5.Fit(self) |
146 | self.Layout() |
171 | self.Layout() |
147 | # end wxGlade |
172 | # end wxGlade |
148 | 173 | ||
149 | # Store some of the items, we will need them later |
174 | # Store some of the items, we will need them later |
150 | self.grid_sizer_2 = grid_sizer_2 |
175 | self.grid_sizer_2 = grid_sizer_2 |
151 | self.sizer_5 = sizer_5 |
176 | self.sizer_5 = sizer_5 |
152 | 177 | ||
153 | 178 | ||
154 | def onOK(self, event): # wxGlade: SettingsDialog.<event_handler> |
179 | def onOK(self, event): # wxGlade: SettingsDialog.<event_handler> |
155 | print "Updating parameters" |
180 | print "Updating parameters" |
156 | try: |
181 | try: |
157 | i=0 |
182 | i=0 |
158 | for setting in self.settings.iteritems(): |
183 | for setting in self.settings.iteritems(): |
159 | print setting[0], self.tb[i].GetValue() |
184 | print setting[0], self.tb[i].GetValue() |
160 | setting[1].set(self.tb[i].GetValue()) |
185 | setting[1].set(self.tb[i].GetValue()) |
161 | i += 1 |
186 | i += 1 |
162 | event.Skip() |
187 | event.Skip() |
163 | except: |
188 | except: |
164 | wx.MessageBox("Invalid format for \"%s\" setting." % setting[1].descr) |
189 | wx.MessageBox("Invalid format for \"%s\" setting." % setting[1].descr) |
165 | 190 | ||
166 | # end of class SettingsDialog |
191 | # end of class SettingsDialog |
167 | 192 | ||
168 | 193 | ||
169 | 194 | ||
170 | class MainFrame(wx.Frame): |
195 | class MainFrame(wx.Frame): |
171 | def __init__(self, *args, **kwds): |
196 | def __init__(self, *args, **kwds): |
172 | # begin wxGlade: MainFrame.__init__ |
197 | # begin wxGlade: MainFrame.__init__ |
173 | kwds["style"] = wx.DEFAULT_FRAME_STYLE |
198 | kwds["style"] = wx.DEFAULT_FRAME_STYLE |
174 | wx.Frame.__init__(self, *args, **kwds) |
199 | wx.Frame.__init__(self, *args, **kwds) |
175 | 200 | ||
176 | # Menu Bar |
201 | # Menu Bar |
177 | self.frame_1_menubar = wx.MenuBar() |
202 | self.frame_1_menubar = wx.MenuBar() |
178 | wxglade_tmp_menu = wx.Menu() |
203 | wxglade_tmp_menu = wx.Menu() |
179 | wxglade_tmp_menu.Append(101, "Settings", "", wx.ITEM_NORMAL) |
204 | wxglade_tmp_menu.Append(101, "Settings", "", wx.ITEM_NORMAL) |
180 | wxglade_tmp_menu.Append(150, "Exit", "", wx.ITEM_NORMAL) |
205 | wxglade_tmp_menu.Append(150, "Exit", "", wx.ITEM_NORMAL) |
181 | self.frame_1_menubar.Append(wxglade_tmp_menu, "File") |
206 | self.frame_1_menubar.Append(wxglade_tmp_menu, "File") |
182 | wxglade_tmp_menu = wx.Menu() |
207 | wxglade_tmp_menu = wx.Menu() |
183 | wxglade_tmp_menu.Append(301, "Clear", "", wx.ITEM_NORMAL) |
208 | wxglade_tmp_menu.Append(301, "Clear", "", wx.ITEM_NORMAL) |
184 | wxglade_tmp_menu.Append(302, "Import", "", wx.ITEM_NORMAL) |
209 | wxglade_tmp_menu.Append(302, "Import", "", wx.ITEM_NORMAL) |
185 | self.frame_1_menubar.Append(wxglade_tmp_menu, "TestSet") |
210 | self.frame_1_menubar.Append(wxglade_tmp_menu, "TestSet") |
186 | wxglade_tmp_menu = wx.Menu() |
211 | wxglade_tmp_menu = wx.Menu() |
187 | self.frame_1_menubar.Append(wxglade_tmp_menu, "MK") |
212 | self.frame_1_menubar.Append(wxglade_tmp_menu, "MK") |
188 | wxglade_tmp_menu = wx.Menu() |
213 | wxglade_tmp_menu = wx.Menu() |
189 | self.frame_1_menubar.Append(wxglade_tmp_menu, "Help") |
214 | self.frame_1_menubar.Append(wxglade_tmp_menu, "Help") |
190 | self.SetMenuBar(self.frame_1_menubar) |
215 | self.SetMenuBar(self.frame_1_menubar) |
191 | # Menu Bar end |
216 | # Menu Bar end |
192 | self.Description = wx.StaticText(self, -1, "Description") |
217 | self.Description = wx.StaticText(self, -1, "Description") |
193 | self.text_ctrl_6 = wx.TextCtrl(self, -1, "Test") |
218 | self.tcDescr = wx.TextCtrl(self, -1, "Test") |
194 | self.label_37 = wx.StaticText(self, -1, "Speed(s)") |
219 | self.label_37 = wx.StaticText(self, -1, "Speed(s)") |
195 | self.text_ctrl_9 = wx.TextCtrl(self, -1, "100-200:10") |
220 | self.tcSpeeds = wx.TextCtrl(self, -1, "100-200:10") |
196 | self.label_35 = wx.StaticText(self, -1, "Motor(s)") |
221 | self.label_35 = wx.StaticText(self, -1, "Motor(s)") |
197 | self.text_ctrl_7 = wx.TextCtrl(self, -1, "1") |
222 | self.tcMotors = wx.TextCtrl(self, -1, "1") |
198 | self.label_38 = wx.StaticText(self, -1, "") |
223 | self.label_38 = wx.StaticText(self, -1, "") |
199 | self.text_ctrl_10 = wx.TextCtrl(self, -1, "") |
224 | self.text_ctrl_10 = wx.TextCtrl(self, -1, "") |
200 | self.label_36 = wx.StaticText(self, -1, "Channel") |
225 | self.label_36 = wx.StaticText(self, -1, "Channel(s)") |
201 | self.text_ctrl_8 = wx.TextCtrl(self, -1, "6") |
226 | self.tcChannels = wx.TextCtrl(self, -1, "6") |
202 | self.label_39 = wx.StaticText(self, -1, "") |
227 | self.label_39 = wx.StaticText(self, -1, "") |
203 | self.text_ctrl_11 = wx.TextCtrl(self, -1, "") |
228 | self.text_ctrl_11 = wx.TextCtrl(self, -1, "") |
204 | self.button_4 = wx.Button(self, -1, "Start") |
229 | self.button_4 = wx.Button(self, -1, "Start") |
205 | self.GraphPanel = wx.Panel(self, -1) |
230 | self.GraphPanel = wx.Panel(self, -1) |
206 | self.label_40 = wx.StaticText(self, -1, "Graph Type ") |
231 | self.label_40 = wx.StaticText(self, -1, "Graph Type ") |
207 | self.graphTypeChoice = wx.Choice(self, -1, choices=["Raw Signal", "Filtered Signal", "Spectrum"]) |
232 | self.graphTypeChoice = wx.Choice(self, -1, choices=["Raw Signal", "Filtered Signal", "Spectrum"]) |
208 | self.label_41 = wx.StaticText(self, -1, "Y Axis Range ") |
233 | self.label_41 = wx.StaticText(self, -1, "Y Axis Range ") |
209 | self.yAxisChoice = wx.Choice(self, -1, choices=["25", "50", "100", "200"]) |
234 | self.yAxisChoice = wx.Choice(self, -1, choices=["25", "50", "100", "200"]) |
210 | self.TestListCtrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER) |
235 | self.TestListCtrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER) |
211 | 236 | ||
212 | self.__set_properties() |
237 | self.__set_properties() |
213 | self.__do_layout() |
238 | self.__do_layout() |
214 | 239 | ||
215 | self.Bind(wx.EVT_MENU, self.OnSettings, id=101) |
240 | self.Bind(wx.EVT_MENU, self.OnSettings, id=101) |
216 | self.Bind(wx.EVT_MENU, self.onClear, id=301) |
241 | self.Bind(wx.EVT_MENU, self.onClear, id=301) |
217 | self.Bind(wx.EVT_MENU, self.OnImport, id=302) |
242 | self.Bind(wx.EVT_MENU, self.OnImport, id=302) |
218 | self.Bind(wx.EVT_BUTTON, self.onStartMeasure, self.button_4) |
243 | self.Bind(wx.EVT_BUTTON, self.onStartMeasure, self.button_4) |
219 | self.Bind(wx.EVT_CHOICE, self.onGraphTypeChange, self.graphTypeChoice) |
244 | self.Bind(wx.EVT_CHOICE, self.onGraphTypeChange, self.graphTypeChoice) |
220 | self.Bind(wx.EVT_CHOICE, self.onYAxisChange, self.yAxisChoice) |
245 | self.Bind(wx.EVT_CHOICE, self.onYAxisChange, self.yAxisChoice) |
221 | # end wxGlade |
246 | # end wxGlade |
222 | 247 | ||
223 | def setApp(self, app): |
248 | def setApp(self, app): |
224 | self.app = app |
249 | self.app = app |
225 | 250 | ||
226 | def __set_properties(self): |
251 | def __set_properties(self): |
227 | # begin wxGlade: MainFrame.__set_properties |
252 | # begin wxGlade: MainFrame.__set_properties |
228 | self.SetTitle("VibrationTest") |
253 | self.SetTitle("VibrationTest") |
229 | self.SetSize((850, 700)) |
254 | self.SetSize((850, 700)) |
230 | self.Description.SetMinSize((53, 13)) |
255 | self.Description.SetMinSize((53, 13)) |
231 | self.button_4.SetMinSize((80, 80)) |
256 | self.button_4.SetMinSize((80, 80)) |
232 | self.GraphPanel.SetMinSize((800,300)) |
257 | self.GraphPanel.SetMinSize((800,300)) |
233 | self.graphTypeChoice.SetSelection(0) |
258 | self.graphTypeChoice.SetSelection(0) |
234 | self.yAxisChoice.SetSelection(1) |
259 | self.yAxisChoice.SetSelection(1) |
235 | self.TestListCtrl.SetMinSize((800,300)) |
260 | self.TestListCtrl.SetMinSize((800,300)) |
236 | # end wxGlade |
261 | # end wxGlade |
237 | 262 | ||
238 | def __do_layout(self): |
263 | def __do_layout(self): |
239 | # begin wxGlade: MainFrame.__do_layout |
264 | # begin wxGlade: MainFrame.__do_layout |
240 | sizer_3 = wx.BoxSizer(wx.HORIZONTAL) |
265 | sizer_3 = wx.BoxSizer(wx.HORIZONTAL) |
241 | sizer_8 = wx.BoxSizer(wx.VERTICAL) |
266 | sizer_8 = wx.BoxSizer(wx.VERTICAL) |
242 | sizer_11 = wx.BoxSizer(wx.VERTICAL) |
267 | sizer_11 = wx.BoxSizer(wx.VERTICAL) |
243 | sizer_12 = wx.BoxSizer(wx.HORIZONTAL) |
268 | sizer_12 = wx.BoxSizer(wx.HORIZONTAL) |
244 | sizer_9 = wx.BoxSizer(wx.HORIZONTAL) |
269 | sizer_9 = wx.BoxSizer(wx.HORIZONTAL) |
245 | sizer_10 = wx.BoxSizer(wx.HORIZONTAL) |
270 | sizer_10 = wx.BoxSizer(wx.HORIZONTAL) |
246 | grid_sizer_1 = wx.GridSizer(3, 4, 4, 5) |
271 | grid_sizer_1 = wx.GridSizer(3, 4, 4, 5) |
247 | sizer_3.Add((20, 20), 0, 0, 0) |
272 | sizer_3.Add((20, 20), 0, 0, 0) |
248 | sizer_8.Add((20, 20), 0, 0, 0) |
273 | sizer_8.Add((20, 20), 0, 0, 0) |
249 | grid_sizer_1.Add(self.Description, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
274 | grid_sizer_1.Add(self.Description, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
250 | grid_sizer_1.Add(self.text_ctrl_6, 0, 0, 0) |
275 | grid_sizer_1.Add(self.tcDescr, 0, 0, 0) |
251 | grid_sizer_1.Add(self.label_37, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
276 | grid_sizer_1.Add(self.label_37, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
252 | grid_sizer_1.Add(self.text_ctrl_9, 0, 0, 0) |
277 | grid_sizer_1.Add(self.tcSpeeds, 0, 0, 0) |
253 | grid_sizer_1.Add(self.label_35, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
278 | grid_sizer_1.Add(self.label_35, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
254 | grid_sizer_1.Add(self.text_ctrl_7, 0, 0, 0) |
279 | grid_sizer_1.Add(self.tcMotors, 0, 0, 0) |
255 | grid_sizer_1.Add(self.label_38, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
280 | grid_sizer_1.Add(self.label_38, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
256 | grid_sizer_1.Add(self.text_ctrl_10, 0, 0, 0) |
281 | grid_sizer_1.Add(self.text_ctrl_10, 0, 0, 0) |
257 | grid_sizer_1.Add(self.label_36, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
282 | grid_sizer_1.Add(self.label_36, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
258 | grid_sizer_1.Add(self.text_ctrl_8, 0, 0, 0) |
283 | grid_sizer_1.Add(self.tcChannels, 0, 0, 0) |
259 | grid_sizer_1.Add(self.label_39, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
284 | grid_sizer_1.Add(self.label_39, 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 0) |
260 | grid_sizer_1.Add(self.text_ctrl_11, 0, 0, 0) |
285 | grid_sizer_1.Add(self.text_ctrl_11, 0, 0, 0) |
261 | sizer_9.Add(grid_sizer_1, 0, 0, 0) |
286 | sizer_9.Add(grid_sizer_1, 0, 0, 0) |
262 | sizer_10.Add((50, 20), 0, 0, 0) |
287 | sizer_10.Add((50, 20), 0, 0, 0) |
263 | sizer_10.Add(self.button_4, 0, wx.ALIGN_CENTER_VERTICAL, 0) |
288 | sizer_10.Add(self.button_4, 0, wx.ALIGN_CENTER_VERTICAL, 0) |
264 | sizer_9.Add(sizer_10, 1, wx.EXPAND, 0) |
289 | sizer_9.Add(sizer_10, 1, wx.EXPAND, 0) |
265 | sizer_8.Add(sizer_9, 0, 0, 0) |
290 | sizer_8.Add(sizer_9, 0, 0, 0) |
266 | sizer_8.Add((20, 30), 0, 0, 0) |
291 | sizer_8.Add((20, 30), 0, 0, 0) |
267 | sizer_11.Add(self.GraphPanel, 1, wx.EXPAND, 0) |
292 | sizer_11.Add(self.GraphPanel, 1, wx.EXPAND, 0) |
268 | sizer_11.Add((20, 5), 0, 0, 0) |
293 | sizer_11.Add((20, 5), 0, 0, 0) |
269 | sizer_12.Add(self.label_40, 0, wx.ALIGN_CENTER_VERTICAL, 0) |
294 | sizer_12.Add(self.label_40, 0, wx.ALIGN_CENTER_VERTICAL, 0) |
270 | sizer_12.Add(self.graphTypeChoice, 0, 0, 0) |
295 | sizer_12.Add(self.graphTypeChoice, 0, 0, 0) |
271 | sizer_12.Add((40, 20), 0, 0, 0) |
296 | sizer_12.Add((40, 20), 0, 0, 0) |
272 | sizer_12.Add(self.label_41, 0, wx.ALIGN_CENTER_VERTICAL, 0) |
297 | sizer_12.Add(self.label_41, 0, wx.ALIGN_CENTER_VERTICAL, 0) |
273 | sizer_12.Add(self.yAxisChoice, 0, 0, 0) |
298 | sizer_12.Add(self.yAxisChoice, 0, 0, 0) |
274 | sizer_11.Add(sizer_12, 0, 0, 0) |
299 | sizer_11.Add(sizer_12, 0, 0, 0) |
275 | sizer_8.Add(sizer_11, 0, 0, 0) |
300 | sizer_8.Add(sizer_11, 0, 0, 0) |
276 | sizer_8.Add((20, 30), 0, 0, 0) |
301 | sizer_8.Add((20, 30), 0, 0, 0) |
277 | sizer_8.Add(self.TestListCtrl, 1, 0, 0) |
302 | sizer_8.Add(self.TestListCtrl, 1, 0, 0) |
278 | sizer_8.Add((20, 20), 0, 0, 0) |
303 | sizer_8.Add((20, 20), 0, 0, 0) |
279 | sizer_3.Add(sizer_8, 1, wx.EXPAND, 0) |
304 | sizer_3.Add(sizer_8, 1, wx.EXPAND, 0) |
280 | self.SetSizer(sizer_3) |
305 | self.SetSizer(sizer_3) |
281 | self.Layout() |
306 | self.Layout() |
282 | self.SetSize((850, 700)) |
307 | self.SetSize((850, 700)) |
283 | # end wxGlade |
308 | # end wxGlade |
284 | 309 | ||
285 | # List events |
310 | # List events |
286 | self.TestListCtrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTestSelected, self.TestListCtrl) |
311 | self.TestListCtrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTestSelected, self.TestListCtrl) |
287 | 312 | ||
288 | # Configure Graph |
313 | # Configure Graph |
289 | self.client = wx.lib.plot.PlotCanvas(self.GraphPanel, size=(800,300)) |
314 | self.client = wx.lib.plot.PlotCanvas(self.GraphPanel, size=(800,300)) |
290 | 315 | ||
291 | self.client.SetPointLabelFunc(self.DrawPointLabel) |
316 | self.client.SetPointLabelFunc(self.DrawPointLabel) |
292 | 317 | ||
293 | self.client.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL)) |
318 | self.client.SetFont(wx.Font(10,wx.SWISS,wx.NORMAL,wx.NORMAL)) |
294 | self.client.SetFontSizeAxis(10) |
319 | self.client.SetFontSizeAxis(10) |
295 | self.client.SetFontSizeLegend(7) |
320 | self.client.SetFontSizeLegend(7) |
296 | self.client.setLogScale((False,False)) |
321 | self.client.setLogScale((False,False)) |
297 | 322 | ||
298 | 323 | ||
299 | # Configure TestListCtrl |
324 | # Configure TestListCtrl |
300 | self.TestListCtrl.InsertColumn(0, "Description") |
325 | self.TestListCtrl.InsertColumn(0, "Description") |
301 | self.TestListCtrl.InsertColumn(1, "Speed") |
326 | self.TestListCtrl.InsertColumn(1, "Speed") |
302 | self.TestListCtrl.InsertColumn(2, "Channel") |
327 | self.TestListCtrl.InsertColumn(2, "Channel") |
303 | self.TestListCtrl.InsertColumn(3, "Vibration Value") |
328 | self.TestListCtrl.InsertColumn(3, "Vibration Value") |
304 | self.TestListCtrl.SetColumnWidth(3, 500) |
329 | self.TestListCtrl.SetColumnWidth(3, 500) |
305 | 330 | ||
306 | def DrawPointLabel(self, dc, mDataDict): |
331 | def DrawPointLabel(self, dc, mDataDict): |
307 | """This is the fuction that defines how the pointLabels are plotted |
332 | """This is the fuction that defines how the pointLabels are plotted |
308 | dc - DC that will be passed |
333 | dc - DC that will be passed |
309 | mDataDict - Dictionary of data that you want to use for the pointLabel |
334 | mDataDict - Dictionary of data that you want to use for the pointLabel |
310 | 335 | ||
311 | As an example I have decided I want a box at the curve point |
336 | As an example I have decided I want a box at the curve point |
312 | with some text information about the curve plotted below. |
337 | with some text information about the curve plotted below. |
313 | Any wxDC method can be used. |
338 | Any wxDC method can be used. |
314 | """ |
339 | """ |
315 | # ---------- |
340 | # ---------- |
316 | dc.SetPen(wx.Pen(wx.BLACK)) |
341 | dc.SetPen(wx.Pen(wx.BLACK)) |
317 | dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) ) |
342 | dc.SetBrush(wx.Brush( wx.BLACK, wx.SOLID ) ) |
318 | 343 | ||
319 | sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point |
344 | sx, sy = mDataDict["scaledXY"] #scaled x,y of closest point |
320 | dc.DrawRectangle( sx-5,sy-5, 10, 10) #10by10 square centered on point |
345 | dc.DrawRectangle( sx-5,sy-5, 10, 10) #10by10 square centered on point |
321 | px,py = mDataDict["pointXY"] |
346 | px,py = mDataDict["pointXY"] |
322 | cNum = mDataDict["curveNum"] |
347 | cNum = mDataDict["curveNum"] |
323 | pntIn = mDataDict["pIndex"] |
348 | pntIn = mDataDict["pIndex"] |
324 | legend = mDataDict["legend"] |
349 | legend = mDataDict["legend"] |
325 | #make a string to display |
350 | #make a string to display |
326 | s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn) |
351 | s = "Crv# %i, '%s', Pt. (%.2f,%.2f), PtInd %i" %(cNum, legend, px, py, pntIn) |
327 | dc.DrawText(s, sx , sy+1) |
352 | dc.DrawText(s, sx , sy+1) |
328 | # ----------- |
353 | # ----------- |
329 | 354 | ||
330 | 355 | ||
331 | def onNewTest(self, test): |
356 | def onNewTest(self, test): |
332 | index = self.TestListCtrl.InsertStringItem(sys.maxint, test.descr) |
357 | index = self.TestListCtrl.InsertStringItem(sys.maxint, test.descr) |
333 | self.TestListCtrl.SetStringItem(index, 1, str(test.speed)) |
358 | self.TestListCtrl.SetStringItem(index, 1, str(test.speed)) |
334 | self.TestListCtrl.SetStringItem(index, 2, test.channel) |
359 | self.TestListCtrl.SetStringItem(index, 2, test.channel) |
335 | 360 | ||
336 | vv = int(test.getVibValue()) |
361 | vv = int(test.getVibValue()) |
337 | vvs = "|%s| (%d)" % ("----------------------------------------------------------------------------------------------------"[0:min(vv,100)], vv) |
362 | vvs = "|%s| (%d)" % ("----------------------------------------------------------------------------------------------------"[0:min(vv,100)], vv) |
338 | self.TestListCtrl.SetStringItem(index, 3, vvs) |
363 | self.TestListCtrl.SetStringItem(index, 3, vvs) |
339 | if (index == 0): |
- | |
340 | self.TestListCtrl.Select(index) |
364 | self.TestListCtrl.Select(index) |
341 | 365 | ||
342 | 366 | ||
343 | def OnTestSelected(self, event): |
367 | def OnTestSelected(self, event): |
344 | testId = event.m_itemIndex |
368 | testId = event.m_itemIndex |
345 | print "Test Selected id=%d" % (testId) |
369 | print "Test Selected id=%d" % (testId) |
346 | self.activeTestId = testId |
370 | self.activeTestId = testId |
347 | self.drawGraph() |
371 | self.drawGraph() |
348 | 372 | ||
349 | def drawGraph(self): |
373 | def drawGraph(self): |
350 | 374 | ||
351 | y = int(self.yAxisChoice.GetStringSelection()) |
375 | y = int(self.yAxisChoice.GetStringSelection()) |
352 | 376 | ||
353 | nbSelected = self.TestListCtrl.SelectedItemCount |
377 | nbSelected = self.TestListCtrl.SelectedItemCount |
354 | 378 | ||
355 | if nbSelected > 1: |
379 | if nbSelected > 1: |
356 | self.graphTypeChoice.Disable() |
380 | self.graphTypeChoice.Disable() |
357 | x = 1 |
381 | x = 1 |
358 | data = [] |
382 | data = [] |
359 | idx = self.TestListCtrl.GetFirstSelected() |
383 | idx = self.TestListCtrl.GetFirstSelected() |
360 | while idx != -1: |
384 | while idx != -1: |
361 | data.append([x,self.app.getTest(idx).getVibValue()]) |
385 | data.append([x,self.app.getTest(idx).getVibValue()]) |
362 | x += 1 |
386 | x += 1 |
363 | idx = self.TestListCtrl.GetNextSelected(idx) |
387 | idx = self.TestListCtrl.GetNextSelected(idx) |
364 | line = wx.lib.plot.PolyLine(data, legend= 'Vibrations', colour='red', width=2) |
388 | line = wx.lib.plot.PolyLine(data, legend= 'Vibrations', colour='red', width=2) |
365 | markers = wx.lib.plot.PolyMarker(data, legend= '', colour='red', marker='circle',size=2) |
389 | markers = wx.lib.plot.PolyMarker(data, legend= '', colour='red', marker='circle',size=2) |
366 | title = "Comparing tests" |
390 | title = "Comparing tests" |
367 | self.client.Draw(wx.lib.plot.PlotGraphics([line, markers], title, "Test", "Vibration Value"), xAxis=(1,max(x,10)), yAxis=(0,y)) |
391 | self.client.Draw(wx.lib.plot.PlotGraphics([line, markers], title, "Test", "Vibration Value"), xAxis=(1,max(x,10)), yAxis=(0,y)) |
368 | self.client.SetEnableGrid('Horizontal') |
392 | self.client.SetEnableGrid('Horizontal') |
369 | 393 | ||
370 | else: |
394 | else: |
371 | self.graphTypeChoice.Enable() |
395 | self.graphTypeChoice.Enable() |
372 | vibTest = self.app.getTest(self.activeTestId) |
396 | vibTest = self.app.getTest(self.activeTestId) |
373 | nb = vibTest.getDataLen() |
397 | nb = vibTest.getDataLen() |
374 | 398 | ||
375 | if self.graphTypeChoice.GetSelection() == 0: |
399 | if self.graphTypeChoice.GetSelection() == 0: |
376 | xydata = _Numeric.linspace(0,0.09*nb,2*nb) |
400 | xydata = _Numeric.linspace(0,0.09*nb,2*nb) |
377 | xydata.shape = (nb, 2) |
401 | xydata.shape = (nb, 2) |
378 | xydata[:,1] = vibTest.getRawData() |
402 | xydata[:,1] = vibTest.getRawData() |
379 | line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2) |
403 | line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2) |
380 | 404 | ||
381 | title = "Raw Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed) |
405 | title = "Raw Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed) |
382 | self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y)) |
406 | self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y)) |
383 | self.client.SetEnableGrid('Horizontal') |
407 | self.client.SetEnableGrid('Horizontal') |
384 | 408 | ||
385 | if self.graphTypeChoice.GetSelection() == 1: |
409 | if self.graphTypeChoice.GetSelection() == 1: |
386 | xydata = _Numeric.linspace(0,0.09*nb,2*nb) |
410 | xydata = _Numeric.linspace(0,0.09*nb,2*nb) |
387 | xydata.shape = (nb, 2) |
411 | xydata.shape = (nb, 2) |
388 | xydata[:,1] = vibTest.getFilteredData() |
412 | xydata[:,1] = vibTest.getFilteredData() |
389 | line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2) |
413 | line = wx.lib.plot.PolyLine(xydata, legend= 'Raw Data', colour='red', width=2) |
390 | 414 | ||
391 | title = "Filtered Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed) |
415 | title = "Filtered Signal: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed) |
392 | self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y)) |
416 | self.client.Draw(wx.lib.plot.PlotGraphics([line], title, "Time (ms)", "Acc"), yAxis= (-y,y)) |
393 | self.client.SetEnableGrid('Horizontal') |
417 | self.client.SetEnableGrid('Horizontal') |
394 | 418 | ||
395 | elif self.graphTypeChoice.GetSelection() == 2: |
419 | elif self.graphTypeChoice.GetSelection() == 2: |
396 | xydata = _Numeric.linspace(0,5555,nb) |
420 | xydata = _Numeric.linspace(0,5555,nb) |
397 | xydata.shape = (nb/2, 2) |
421 | xydata.shape = (nb/2, 2) |
398 | 422 | ||
399 | xydata[:,1] = vibTest.getSpectrum() |
423 | xydata[:,1] = vibTest.getSpectrum() |
400 | 424 | ||
401 | line = wx.lib.plot.PolyLine(xydata, legend= 'Spectrum', colour='red') |
425 | line = wx.lib.plot.PolyLine(xydata, legend= 'Spectrum', colour='red') |
402 | markers = wx.lib.plot.PolyMarker(xydata, legend= '', colour='red', marker='circle',size=2) |
426 | markers = wx.lib.plot.PolyMarker(xydata, legend= '', colour='red', marker='circle',size=2) |
403 | 427 | ||
404 | title = "Spectrum: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed) |
428 | title = "Spectrum: %s %s %d" %(vibTest.descr, vibTest.channel, vibTest.speed) |
405 | self.client.Draw(wx.lib.plot.PlotGraphics([line,markers], title, "Freq (Hz)", "Acc"), xAxis=(0,200), yAxis= (-0,y)) |
429 | self.client.Draw(wx.lib.plot.PlotGraphics([line,markers], title, "Freq (Hz)", "Acc"), xAxis=(0,200), yAxis= (-0,y)) |
406 | self.client.SetEnableGrid(True) |
430 | self.client.SetEnableGrid(True) |
407 | 431 | ||
408 | 432 | ||
409 | def OnImport(self, event): # wxGlade: MainFrame.<event_handler> |
433 | def OnImport(self, event): # wxGlade: MainFrame.<event_handler> |
410 | dlg = wx.FileDialog( |
434 | dlg = wx.FileDialog( |
411 | self, message="Choose a file", |
435 | self, message="Choose a file", |
412 | defaultDir=os.getcwd(), |
436 | defaultDir=os.getcwd(), |
413 | defaultFile="*.txt", |
437 | defaultFile="*.txt", |
414 | wildcard="", |
438 | wildcard="", |
415 | style=wx.OPEN | wx.CHANGE_DIR |
439 | style=wx.OPEN | wx.CHANGE_DIR |
416 | ) |
440 | ) |
417 | if dlg.ShowModal() == wx.ID_OK: |
441 | if dlg.ShowModal() == wx.ID_OK: |
418 | paths = dlg.GetPaths(); |
442 | paths = dlg.GetPaths(); |
419 | self.app.Import(paths[0]) |
443 | self.app.Import(paths[0]) |
420 | dlg.Destroy() |
444 | dlg.Destroy() |
421 | 445 | ||
422 | def onYAxisChange(self, event): # wxGlade: MainFrame.<event_handler> |
446 | def onYAxisChange(self, event): # wxGlade: MainFrame.<event_handler> |
423 | self.drawGraph() |
447 | self.drawGraph() |
424 | 448 | ||
425 | def onGraphTypeChange(self, event): # wxGlade: MainFrame.<event_handler> |
449 | def onGraphTypeChange(self, event): # wxGlade: MainFrame.<event_handler> |
426 | self.drawGraph() |
450 | self.drawGraph() |
427 | 451 | ||
428 | def onClear(self, event): # wxGlade: MainFrame.<event_handler> |
452 | def onClear(self, event): # wxGlade: MainFrame.<event_handler> |
429 | print "Event handler `onClear' not implemented" |
453 | print "Event handler `onClear' not implemented" |
430 | event.Skip() |
454 | event.Skip() |
431 | 455 | ||
432 | def OnSettings(self, event): # wxGlade: MainFrame.<event_handler> |
456 | def OnSettings(self, event): # wxGlade: MainFrame.<event_handler> |
433 | dlg = SettingsDialog(self, -1, "Sample Dialog", size=(350, 200), |
457 | dlg = SettingsDialog(self, -1, "Sample Dialog", size=(350, 200), |
434 | #style=wx.CAPTION | wx.SYSTEM_MENU | wx.THICK_FRAME, |
458 | #style=wx.CAPTION | wx.SYSTEM_MENU | wx.THICK_FRAME, |
435 | style=wx.DEFAULT_DIALOG_STYLE, # & ~wx.CLOSE_BOX |
459 | style=wx.DEFAULT_DIALOG_STYLE, # & ~wx.CLOSE_BOX |
436 | ) |
460 | ) |
437 | dlg.CenterOnScreen() |
461 | dlg.CenterOnScreen() |
438 | val = dlg.ShowModal() # this does not return until the dialog is closed. |
462 | val = dlg.ShowModal() # this does not return until the dialog is closed. |
439 | dlg.Destroy() |
463 | dlg.Destroy() |
440 | self.app.onSettingsChanged() |
464 | self.app.onSettingsChanged() |
441 | 465 | ||
442 | def onStartMeasure(self, event): # wxGlade: MainFrame.<event_handler> |
466 | def onStartMeasure(self, event): # wxGlade: MainFrame.<event_handler> |
- | 467 | # Collect measure parameters |
|
- | 468 | mp = MeasureParameters() |
|
- | 469 | mp.descr = self.tcDescr.GetValue() |
|
- | 470 | mp.motors = map(int,self.tcMotors.GetValue().split(',')) |
|
- | 471 | mp.channels = map(int,self.tcChannels.GetValue().split(',')) |
|
- | 472 | s = self.tcSpeeds.GetValue() |
|
- | 473 | if s.count("-") == 1: |
|
- | 474 | # assume from-to:step format |
|
- | 475 | s = s.split("-") |
|
- | 476 | if len(s) != 2: raise Exception("Invalid format") |
|
- | 477 | s[1] = s[1].split(":") |
|
- | 478 | if len(s[1]) != 2: raise Exception("Invalid format") |
|
- | 479 | mp.speeds = range(int(s[0]),int(s[1][0])+int(s[1][1]),int(s[1][1])) |
|
- | 480 | else: |
|
- | 481 | mp.speeds = s.split(',') |
|
443 | 482 | ||
444 | # create the dialog that will show the satus |
483 | # create the dialog that will show the satus |
445 | dlg = MeasureDialog(self) |
484 | dlg = MeasureDialog(self) |
446 | dlg.CenterOnScreen() |
485 | dlg.CenterOnScreen() |
- | 486 | ||
447 | # Signal that application |
487 | # Signal the application |
448 | self.app.startMeasure(dlg) |
488 | self.app.startMeasure(mp, dlg) |
- | 489 | ||
449 | # Show the dialog |
490 | # Show the dialog |
450 | val = dlg.ShowModal() # this does not return until the dialog is closed. |
491 | val = dlg.ShowModal() # this does not return until the dialog is closed. |
451 | dlg.Destroy() |
492 | dlg.Destroy() |
452 | 493 | ||
453 | # end of class MainFrame |
494 | # end of class MainFrame |
454 | 495 | ||
455 | class Setting: |
496 | class Setting: |
456 | def __init__(self, descr, defaultValue): |
497 | def __init__(self, descr, defaultValue): |
457 | self.descr = descr |
498 | self.descr = descr |
458 | self.value = defaultValue |
499 | self.value = defaultValue |
459 | 500 | ||
460 | def set(self, newValue): |
501 | def set(self, newValue): |
461 | if isinstance(self.value, int): |
502 | if isinstance(self.value, int): |
462 | self.value = int(newValue) |
503 | self.value = int(newValue) |
463 | else: |
504 | else: |
464 | self.value = str(newValue) |
505 | self.value = str(newValue) |
- | 506 | ||
- | 507 | class MeasureParameters: |
|
465 | 508 | pass |
|
466 | 509 | ||
- | 510 | class MeasureThread: |
|
- | 511 | def __init__(self, measureParameters, evtConsumer): |
|
467 | class MeasureThread: |
512 | self.mk = mkProto.MkComm() |
- | 513 | self.param = measureParameters |
|
- | 514 | self.evtConsumer = evtConsumer |
|
468 | def __init__(self, evtConsumer): |
515 | self.cancel = False |
469 | self.evtConsumer = evtConsumer |
516 | self.running = False |
470 | 517 | ||
471 | def start(self): |
518 | def start(self): |
472 | thread.start_new_thread(self._run, ()) |
519 | thread.start_new_thread(self._run, ()) |
473 | 520 | ||
474 | def _run(self): |
521 | def stop(self): |
- | 522 | self.cancel = True |
|
475 | i=0 |
523 | |
476 | for i in range(20): |
524 | def _testCancel(self): |
477 | time.sleep(0.5) |
525 | if self.cancel: |
- | 526 | raise Exception("Operation cancelled") |
|
478 | evt = MeasStatusUpdateEvent(running=True, msg="Hello %d" % i) |
527 | |
479 | wx.PostEvent(self.evtConsumer, evt) |
528 | def _sendEvent(self, msg, error=False): |
480 | evt = MeasStatusUpdateEvent(running=False, msg="Done") |
529 | evt = MeasStatusUpdateEvent(running=self.running, msg=msg, error=error) |
- | 530 | wx.PostEvent(self.evtConsumer, evt) |
|
- | 531 | ||
- | 532 | def _setMotorSpeed(self, speed, settlingTime): |
|
- | 533 | speeds = [0,0,0,0] |
|
- | 534 | for motor in self.param.motors: |
|
- | 535 | speeds[motor-1] = speed |
|
- | 536 | for i in range(int(settlingTime*10)): |
|
- | 537 | self._testCancel() |
|
- | 538 | self.mk.setMotorTest(speeds) |
|
- | 539 | time.sleep(.1) |
|
- | 540 | ||
- | 541 | ||
- | 542 | def _run(self): |
|
- | 543 | self.running = True |
|
- | 544 | self._sendEvent("Starting test \"%s\"" % self.param.descr) |
|
- | 545 | ||
- | 546 | try: |
|
- | 547 | self._sendEvent("Opening SerialPort \"%s\"" % self.param.serialPort) |
|
- | 548 | self.mk.open(comPort=self.param.serialPort) |
|
- | 549 | ||
- | 550 | msg = self.mk.getVersionMsg() |
|
- | 551 | version = msg.getVersion() |
|
- | 552 | self._sendEvent("Version: %d.%d" % version) |
|
- | 553 | ||
- | 554 | msg = self.mk.getDebugMsg() |
|
- | 555 | voltage = msg.getVoltage() |
|
- | 556 | if (voltage == 0): |
|
- | 557 | minVoltage = 0 |
|
- | 558 | else: |
|
- | 559 | if (voltage > 4.2*3): |
|
- | 560 | minVoltage = 4*3.5 |
|
- | 561 | else: |
|
- | 562 | minVoltage = 3*3.5 |
|
- | 563 | ||
- | 564 | self._sendEvent("Voltage: %2.1fV" % voltage) |
|
- | 565 | self._sendEvent("Minimum Voltage: %2.1fV" % minVoltage) |
|
- | 566 | ||
- | 567 | self._sendEvent("Starting motor(s) (speed=%d)... " % self.param.motorStartupSpeed) |
|
- | 568 | self._setMotorSpeed(self.param.motorStartupSpeed, self.param.motorStartupSettlingTime) |
|
- | 569 | ||
- | 570 | for speed in self.param.speeds: |
|
- | 571 | self._sendEvent("Changing motor speed to %d... " % speed) |
|
- | 572 | self._setMotorSpeed(speed, 1) |
|
- | 573 | ||
- | 574 | for channel in self.param.channels: |
|
- | 575 | self._setMotorSpeed(speed, .1) |
|
- | 576 | self._sendEvent("Getting data from channel %s" % CHANNEL_NAMES[channel]) |
|
- | 577 | data = self.mk.doVibrationTest(1000, channel) |
|
- | 578 | ||
- | 579 | vt = VibTest(self.param.descr, self.param.motors, speed, CHANNEL_NAMES[channel], data) |
|
- | 580 | evt = MeasDataEvent(vibTest = vt) |
|
- | 581 | wx.PostEvent(self.evtConsumer, evt) |
|
- | 582 | ||
- | 583 | self._sendEvent("Done !") |
|
- | 584 | ||
- | 585 | except Exception, e: |
|
- | 586 | self._sendEvent("Exception \"%s\"" % e, error=True) |
|
- | 587 | ||
481 | wx.PostEvent(self.evtConsumer, evt) |
588 | self.running = False |
482 | 589 | self._sendEvent("") |
|
483 | 590 | ||
484 | 591 | ||
485 | class VibTest: |
592 | class VibTest: |
486 | def __init__(self, descr, motor, speed, channel, rawData): |
593 | def __init__(self, descr, motor, speed, channel, rawData): |
487 | self.descr = descr |
594 | self.descr = descr |
488 | self.motor = motor |
595 | self.motor = motor |
489 | self.speed = speed |
596 | self.speed = speed |
490 | self.channel = channel |
597 | self.channel = channel |
491 | 598 | ||
492 | self.dataLen = len(rawData) |
599 | self.dataLen = len(rawData) |
493 | 600 | ||
494 | self.rawData = _Numeric.array(rawData) |
601 | self.rawData = _Numeric.array(rawData) |
495 | self.dc = self.rawData.mean() |
602 | self.dc = self.rawData.mean() |
496 | self.rawData -= self.dc |
603 | self.rawData -= self.dc |
497 | 604 | ||
498 | self.fft = _Numeric.fft.rfft(self.rawData) |
605 | self.fft = _Numeric.fft.rfft(self.rawData) |
499 | 606 | ||
500 | self.spectrum = None |
607 | self.spectrum = None |
501 | self.filteredData = None |
608 | self.filteredData = None |
502 | 609 | ||
503 | self.vibValue = None |
610 | self.vibValue = None |
504 | 611 | ||
505 | def getDescr(self): |
612 | def getDescr(self): |
506 | return self.Descr |
613 | return self.Descr |
507 | 614 | ||
508 | def getRawData(self): |
615 | def getRawData(self): |
509 | return self.rawData |
616 | return self.rawData |
510 | 617 | ||
511 | def getDataLen(self): |
618 | def getDataLen(self): |
512 | return self.dataLen |
619 | return self.dataLen |
513 | 620 | ||
514 | def getSpectrum(self): |
621 | def getSpectrum(self): |
515 | if self.spectrum == None: |
622 | if self.spectrum == None: |
516 | self.spectrum = _Numeric.absolute(self.fft[1:self.dataLen/2+1]) / (self.dataLen/2) |
623 | self.spectrum = _Numeric.absolute(self.fft[1:self.dataLen/2+1]) / (self.dataLen/2) |
517 | return self.spectrum |
624 | return self.spectrum |
518 | 625 | ||
519 | def getFilteredData(self): |
626 | def getFilteredData(self): |
520 | if self.filteredData == None: |
627 | if self.filteredData == None: |
521 | tmpfft = self.fft.copy() |
628 | tmpfft = self.fft.copy() |
522 | for i in range(0,5): |
629 | for i in range(0,5): |
523 | tmpfft[i] = 0 |
630 | tmpfft[i] = 0 |
524 | for i in range(30, len(tmpfft)): |
631 | for i in range(30, len(tmpfft)): |
525 | tmpfft[i] = 0 |
632 | tmpfft[i] = 0 |
526 | self.filteredData = _Numeric.fft.irfft(tmpfft) |
633 | self.filteredData = _Numeric.fft.irfft(tmpfft) |
527 | return self.filteredData |
634 | return self.filteredData |
528 | 635 | ||
529 | def getVibValue(self): |
636 | def getVibValue(self): |
530 | if self.vibValue == None: |
637 | if self.vibValue == None: |
531 | fd = self.getFilteredData(); |
638 | fd = self.getFilteredData(); |
532 | self.vibValue = max(fd)-min(fd) |
639 | self.vibValue = max(fd)-min(fd) |
533 | return self.vibValue |
640 | return self.vibValue |
534 | 641 | ||
535 | 642 | ||
536 | 643 | ||
537 | class App(wx.App): |
644 | class App(wx.App): |
538 | 645 | ||
539 | SETTINGSFILE = "settings.cfg" |
646 | SETTINGSFILE = "settings.cfg" |
540 | 647 | ||
541 | def __init__(self, par): |
648 | def __init__(self, par): |
542 | self.VibTests = [] |
649 | self.VibTests = [] |
543 | wx.App.__init__(self, par) |
650 | wx.App.__init__(self, par) |
544 | 651 | ||
545 | # Init settings |
652 | # Init settings |
546 | self.settings={} |
653 | self.settings={} |
547 | self.settings["serialport"] = Setting("Serial Port", "COM1") |
654 | self.settings["serialport"] = Setting("Serial Port", "COM1") |
- | 655 | self.settings["startupspeed"] = Setting("Motor Startup Speed", 25) |
|
- | 656 | self.settings["startupsettling"] = Setting("Motor Startup Setting time (s)", 3) |
|
- | 657 | self.settings["serialport"] = Setting("Serial Port", "COM1") |
|
548 | self.settings["hpf"] = Setting("HP Filter cutoff (Hz)", 50) |
658 | self.settings["hpf"] = Setting("HP Filter cutoff (Hz)", 50) |
549 | self.settings["lpf"] = Setting("LP Filter cutoff (Hz)", 400) |
659 | self.settings["lpf"] = Setting("LP Filter cutoff (Hz)", 400) |
550 | 660 | ||
551 | self.readSettings() |
661 | self.readSettings() |
552 | 662 | ||
553 | if len(sys.argv)>1: |
663 | if len(sys.argv)>1: |
554 | self.Import(sys.argv[1]) |
664 | self.Import(sys.argv[1]) |
555 | 665 | ||
556 | 666 | ||
557 | def readSettings(self): |
667 | def readSettings(self): |
558 | print "Reading settings" |
668 | print "Reading settings" |
559 | cp = ConfigParser.ConfigParser() |
669 | cp = ConfigParser.ConfigParser() |
560 | 670 | ||
561 | try: |
671 | try: |
562 | cp.read(App.SETTINGSFILE) |
672 | cp.read(App.SETTINGSFILE) |
563 | for setting in cp.items("DEFAULT"): |
673 | for setting in cp.items("DEFAULT"): |
564 | print " ",setting |
674 | print " ",setting |
565 | try: |
675 | try: |
566 | self.settings[setting[0]].value = setting[1] |
676 | self.settings[setting[0]].set(setting[1]) |
567 | except: |
677 | except: |
568 | print "WARNING, unknown setting" |
678 | print "WARNING, unknown setting" |
569 | except: |
679 | except: |
570 | print "ERROR reading settingsfile" |
680 | print "ERROR reading settingsfile" |
571 | 681 | ||
572 | 682 | ||
573 | def storeSettings(self): |
683 | def storeSettings(self): |
574 | print "Storing settings" |
684 | print "Storing settings" |
575 | 685 | ||
576 | cp = ConfigParser.ConfigParser() |
686 | cp = ConfigParser.ConfigParser() |
577 | for setting in self.settings.iteritems(): |
687 | for setting in self.settings.iteritems(): |
578 | cp.set("", setting[0], setting[1].value) |
688 | cp.set("", setting[0], setting[1].value) |
579 | 689 | ||
580 | file = open(App.SETTINGSFILE, "w") |
690 | file = open(App.SETTINGSFILE, "w") |
581 | cp.write(file) |
691 | cp.write(file) |
582 | file.close() |
692 | file.close() |
583 | 693 | ||
584 | 694 | ||
585 | def onSettingsChanged(self): |
695 | def onSettingsChanged(self): |
586 | self.storeSettings() |
696 | self.storeSettings() |
587 | 697 | ||
- | 698 | def AddTest2(self, vibTest): |
|
- | 699 | self.VibTests.append(vibTest) |
|
- | 700 | self.frame_1.onNewTest(vibTest) |
|
588 | 701 | ||
589 | def AddTest(self, descr, motor, speed, channel, rawData): |
702 | def AddTest(self, descr, motor, speed, channel, rawData): |
590 | test = VibTest(descr, motor, speed, channel, rawData) |
703 | test = VibTest(descr, motor, speed, channel, rawData) |
591 | self.VibTests.append(test) |
704 | self.AddTest2(test) |
592 | self.frame_1.onNewTest(test) |
- | |
593 | 705 | ||
594 | def getTest(self, testId): |
706 | def getTest(self, testId): |
595 | return self.VibTests[testId] |
707 | return self.VibTests[testId] |
596 | 708 | ||
597 | def OnInit(self): |
709 | def OnInit(self): |
598 | wx.InitAllImageHandlers() |
710 | wx.InitAllImageHandlers() |
599 | self.frame_1 = MainFrame(None, -1, "") |
711 | self.frame_1 = MainFrame(None, -1, "") |
600 | self.frame_1.setApp(self); |
712 | self.frame_1.setApp(self); |
601 | self.SetTopWindow(self.frame_1) |
713 | self.SetTopWindow(self.frame_1) |
602 | 714 | ||
603 | self.frame_1.CenterOnScreen() |
715 | self.frame_1.CenterOnScreen() |
604 | self.frame_1.Show() |
716 | self.frame_1.Show() |
605 | return 1 |
717 | return 1 |
606 | 718 | ||
607 | def Import(self, filePath): |
719 | def Import(self, filePath): |
608 | 720 | ||
609 | print "Importing file \"%s\"" % filePath |
721 | print "Importing file \"%s\"" % filePath |
610 | 722 | ||
611 | logfile = open(filePath, "r") |
723 | logfile = open(filePath, "r") |
612 | data = None |
724 | data = None |
613 | 725 | ||
614 | headers = (logfile.readline()).split(',') |
726 | headers = (logfile.readline()).split(',') |
615 | nbCols = len(headers) |
727 | nbCols = len(headers) |
616 | print "NbCols =", nbCols |
728 | print "NbCols =", nbCols |
617 | 729 | ||
618 | data = [] |
730 | data = [] |
619 | descr = [] |
731 | descr = [] |
620 | speed = [] |
732 | speed = [] |
621 | channel = [] |
733 | channel = [] |
622 | for c in range(nbCols): |
734 | for c in range(nbCols): |
623 | data.append([]) |
735 | data.append([]) |
624 | h = headers[c].split(' ') |
736 | h = headers[c].split(' ') |
625 | descr.append(h[0]); |
737 | descr.append(h[0]); |
626 | speed.append(h[1]); |
738 | speed.append(h[1]); |
627 | channel.append(h[2]); |
739 | channel.append(h[2]); |
628 | 740 | ||
629 | for line in logfile: |
741 | for line in logfile: |
630 | values = line.split(',') |
742 | values = line.split(',') |
631 | for i in range(nbCols): |
743 | for i in range(nbCols): |
632 | data[i].append(int(values[i])) |
744 | data[i].append(int(values[i])) |
633 | logfile.close() |
745 | logfile.close() |
634 | 746 | ||
635 | for c in range(nbCols): |
747 | for c in range(nbCols): |
636 | if (len(data[c]) % 2) != 0: |
748 | if (len(data[c]) % 2) != 0: |
637 | data[c].append(data[c][-1]) |
749 | data[c].append(data[c][-1]) |
638 | self.AddTest(descr[c], 0, int(speed[c]), channel[c], data[c]) |
750 | self.AddTest(descr[c], 0, int(speed[c]), channel[c], data[c]) |
639 | 751 | ||
640 | def startMeasure(self, dialog): |
752 | def startMeasure(self, measureParams, dialog): |
- | 753 | print "Start measuring" |
|
- | 754 | ||
- | 755 | measureParams.serialPort = self.settings["serialport"].value |
|
- | 756 | measureParams.motorStartupSpeed = self.settings["startupspeed"].value |
|
641 | print "Start measuring" |
757 | measureParams.motorStartupSettlingTime = self.settings["startupsettling"].value |
642 | 758 | ||
- | 759 | self.measureThread = MeasureThread(measureParams, dialog) |
|
- | 760 | self.measureThread.start() |
|
- | 761 | ||
- | 762 | def cancelMeasurement(self): |
|
- | 763 | print "Measuring CANCEL" |
|
643 | self.measureThread = MeasureThread(dialog) |
764 | |
644 | self.measureThread.start() |
765 | self.measureThread.stop() |
645 | 766 | ||
646 | 767 | ||
647 | 768 | ||
648 | 769 | ||
649 | 770 | ||
650 | 771 | ||
651 | 772 | ||
652 | 773 | ||
653 | # end of class App |
774 | # end of class App |
654 | 775 | ||
655 | if __name__ == "__main__": |
776 | if __name__ == "__main__": |
656 | VibrationTestGui = App(0) |
777 | VibrationTestGui = App(0) |
657 | VibrationTestGui.MainLoop() |
778 | VibrationTestGui.MainLoop() |
658 | 779 |