Code:
#Boa:Dialog:TiltCalibrate
import wx
import Multiply
from PMD import DefaultMultiplier
from time import sleep
from string import digits
from wxdbtools import MySQLInsert, MySQLUpdate, MySQLSelect
SlopeChan = 0
GradeChan = 1
DistChann = 2
CalPhaseButtonText = ["Begin Calibration", "Calibrate Grade", "Calibrate X-Slope", "Can\'t Calibrate"]
CalPhasePromptText = ["Set data collection vehicle in starting position:",
"Rotate the vehicle 180 degrees (in place):",
"Roll the vehicle forward until rear wheels are at starting position",
"Invalid data has been received. Check PMD Setup for further information"]
HETAP_table_sql = """CREATE TABLE `HETAP_Setup`.`setup` (
`setupID` int(4) unsigned NOT NULL auto_increment,
`xctSerNum` varchar(45) NOT NULL default '',
`xAxisSensitivity` decimal(5,3) default NULL,
`yAxisSensitivity` decimal(5,3) default NULL,
`xAxisOffset` decimal(7,6) default NULL,
`yAxisOffset` decimal(7,6) default NULL,
`zAxisSensitivity` decimal(7,6) default NULL,
PRIMARY KEY (`setupID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;"""
def create(parent):
return TiltCalibrate(parent)
[wxID_TILTCALIBRATE, wxID_TILTCALIBRATECALIBRATEBUTTON,
wxID_TILTCALIBRATECANCELBUTTON, wxID_TILTCALIBRATEDONEBUTTON,
wxID_TILTCALIBRATEGRADEOFFSETTEXTCTRL, wxID_TILTCALIBRATEGRADESENSETEXTCTRL,
wxID_TILTCALIBRATEGRADETEXTCTRL, wxID_TILTCALIBRATESERNUMCOMBOBOX,
wxID_TILTCALIBRATESLOPEOFFSETTEXTCTRL, wxID_TILTCALIBRATESLOPESENSETEXTCTRL,
wxID_TILTCALIBRATESLOPETEXTCTRL, wxID_TILTCALIBRATESTATICBITMAP1,
wxID_TILTCALIBRATESTATICTEXT1, wxID_TILTCALIBRATESTATICTEXT2,
wxID_TILTCALIBRATESTATICTEXT3, wxID_TILTCALIBRATESTATICTEXT4,
wxID_TILTCALIBRATESTATICTEXT5, wxID_TILTCALIBRATESTATICTEXT6,
wxID_TILTCALIBRATESTATICTEXT7, wxID_TILTCALIBRATESTATICTEXT8,
wxID_TILTCALIBRATESTATICTEXT9,
] = [wx.NewId() for _init_ctrls in range(21)]
class TiltCalibrate(wx.Dialog):
def _init_ctrls(self, prnt):
# generated method, don't edit
# instantiate widgets
def __init__(self, parent):
self._init_ctrls(parent)
self.publisher = self.Subscribe(parent)
## self.widgetList = [self.gradeSenseTextCtrl, self.slopeSenseTextCtrl,
## ]
self.dbServer = parent.GetDBServer()
self.CheckDatabase()
self.calibPhase = 0
self.bitmapList = []
self.GetCalibBitmaps()
self.staticBitmap1.SetBitmap(self.bitmapList[0])
self.FillFromDB()
self.SetupMultipliers()
def CheckDatabase(self):
dbServer = self.dbServer
if not dbServer.DBExists("HETAP_Setup".lower()):
dbServer.Execute("CREATE DATABASE HETAP_Setup")
dbServer.Execute(HETAP_table_sql)
self.db_is_new = True # probably don't need this flag
else:
self.db_is_new = False
print "db_is_new = ", self.db_is_new
def FillFromDB(self):
varList = []
cursor = self.dbServer.Execute("SELECT * FROM `HETAP_Setup`.`setup`")
if cursor.rowcount:
rows = cursor.fetchall()
for i in range(4):
try:
varList.append(float(rows[0][i+2]))
except TypeError:
varList.append(0)
for row in rows:
self.sernumComboBox.Append(row[1])
self.gradeSense = varList[0]/1000 or Multiply.DefaultTiltSense
self.slopeSense = varList[1]/1000 or Multiply.DefaultTiltSense
self.gradeOffset = varList[2] or Multiply.DefaultOffset
self.slopeOffset = varList[3] or Multiply.DefaultOffset
self.ShowOffsets()
def Subscribe(self, dataSource):
publisher = dataSource.GetPublisher()
publisher.RegisterClientCallback(self.Update)
return publisher
def SetupMultipliers(self):
## Create multipliers and submit them to the publisher
self.gradeMultiplier = gm = Multiply.CrossbowMultiplier(GradeChan, self.gradeOffset, self.gradeSense)
self.slopeMultiplier = sm = Multiply.CrossbowMultiplier(SlopeChan, self.slopeOffset, self.slopeSense)
self.SubmitMultipliers(gm, sm)
def SubmitMultipliers(self, gradeMult, slopeMult):
self.publisher.SetMultiplier(gradeMult)
self.publisher.SetMultiplier(slopeMult)
def ResetMultipliers(self):
gradeMult = DefaultMultiplier(0)
slopeMult = DefaultMultiplier(1)
self.SubmitMultipliers(gradeMult, slopeMult)
self.staticText3.SetLabel("Old calibration data is being reset")
sleep(2)
def Update(self, dataList):
i = self.calibPhase
try:
# Publisher sent valid data to us
self.grade = grade = dataList[GradeChan]
self.slope = slope = dataList[SlopeChan]
if i == 3: # From waiting to begin phase
self.calibPhase = 0
self.SetWidgetText()
except TypeError:
# Publisher can't get valid data
if i == 3:
return
self.slope = slope = 0
self.grade = grade = 0
self.calibPhase = 3 # Set phase to waiting
self.SetWidgetText()
# Upadate calibration display regardless
self.gradeTextCtrl.SetValue("%.1f %%" %grade)
self.slopeTextCtrl.SetValue("%.1f %%" %slope)
def GetCalibBitmaps(self):
for i in range(4):
filename = "calib%d.bmp" %i
bitmap = wx.Bitmap(filename, wx.BITMAP_TYPE_BMP)
self.bitmapList.append(bitmap)
def SetWidgetText(self):
"""Caller must ensure calibration phase is set correctly."""
i = self.calibPhase
buttonText = CalPhaseButtonText[i]
staticText = CalPhasePromptText[i]
self.CalibrateButton.SetLabel(buttonText)
self.staticText3.SetLabel(staticText)
self.staticBitmap1.SetBitmap(self.bitmapList[i])
def NextPhase(self, i):
i += 1
self.calibPhase = i * bool(i % 3)
def PostWarning(self, msg):
wx.MessageBox(msg, "Error", wx.OK|wx.ICON_EXCLAMATION, self)
def ShowOffsets(self):
self.gradeOffsetTextCtrl.SetValue("%.3f V" %self.gradeOffset)
self.slopeOffsetTextCtrl.SetValue("%.3f V" %self.slopeOffset)
def OnCalibrateButton(self, event):
i = self.calibPhase
self.NextPhase(i)
resultList = self.publisher.GetRawData()
if i == 3:
return
if i == 0:
self.p0Grade = resultList[GradeChan]
self.p0Slope = resultList[SlopeChan]
elif i == 1:
p1Grade = resultList[GradeChan]
self.gradeOffset = gradeOffset = (self.p0Grade + p1Grade) / 2.0
# print self.p0Grade, p1Grade, gradeOffset
self.gradeMultiplier.InitMultiplier(gradeOffset, self.gradeSense)
elif i == 2:
p1Slope = resultList[SlopeChan]
self.slopeOffset = slopeOffset = (self.p0Slope + p1Slope) / 2.0
# print self.p0Slope, p1Slope, slopeOffset
self.slopeMultiplier.InitMultiplier(slopeOffset, self.slopeSense)
self.SetWidgetText()
self.ShowOffsets()
def OnTextCtrlChar(self, event):
event.Skip()
def OnDoneButton(self, event):
sernum = self.sernumComboBox.GetValue()
if not sernum:
self.PostWarning("Serial Number field is blank")
return
try:
gradeSense = float(self.gradeSenseTextCtrl.GetValue())
except ValueError:
self.PostWarning("X (Grade) sensitivity field has a bad value in it")
return
try:
slopeSense = float(self.slopeSenseTextCtrl.GetValue())
except ValueError:
self.PostWarning("Y (X-Slope) sensitivity field has a bad value in it")
return
query = MySQLSelect("`HETAP_Setup`.`setup`", xctSerNum=sernum)
cursor = self.dbServer.Execute(query)
nRows = cursor.rowcount
if nRows:
query = MySQLUpdate("`HETAP_Setup`.`setup`", dict(xAxisSensitivity=gradeSense,
yAxisSensitivity=slopeSense, xAxisOffset=self.gradeOffset,
yAxisOffset=self.slopeOffset), {}, xctSerNum=sernum)
else:
query = MySQLInsert("`HETAP_Setup`.`setup`", {}, xctSerNum=sernum,
xAxisSensitivity=gradeSense, yAxisSensitivity=slopeSense,
xAxisOffset=self.gradeOffset, yAxisOffset=self.slopeOffset)
self.dbServer.Execute(query)
self.Hide()
def OnCancelButton(self, event):
self.Hide()