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