#! /bin/env python #------------------------------------------------------------------- # # File: RmMotorFrame.py # Purpose: Motor Display Frame # Created: June 22, 2000 # Author: Lionel PEYRICHOUX # #------------------------------------------------------------------- from Tkinter import * from CaChannel import * from Dialog import Dialog from ConfigMotor import * from Canvas import * from Data import * #=============================================================== # # Description of each Rack Monitor : # * Name RackMonitor = ('CTL_RM_02-01', 'CTL_RM_02-02', 'CTL_RM_02-03', 'CTL_RM_02-04', 'CTL_RM_02-11', 'CTL_RM_02-12', 'CTL_RM_02-13', 'CTL_RM_02-14', 'CTL_RM_02-05', # Smoke Detector to the Dipoles 'CTL_RM_02-15') # Smoke Detector to P1 # End of the description of each Rack Monitor # #=============================================================== #=============================================================== # # Drawing Pot DrPot = ((67,380, 87,390), # D2 Inside (139,344,159,354), # D1 Inside (226,223,236,243), # A2 Top (226,323,236,343), # A2 Bottom (171,278,191,288), # A2 Outside (271,278,291,288), # A2 Inside (322,175,332,195), # A1 Top (322,275,332,295), # A1 Bottom (267,230,287,240), # A1 Outside (367,230,387,240), # A1 Inside (490, 91,500,111), # P1 Top (490,191,500,211), # P1 Bottom (435,146,455,156), # P1 Outside (535,146,555,156), # P1 Inside (586, 43,596, 63), # P2 Top (586,143,596,163), # P2 Bottom (531, 98,551,108), # P2 Outside (631, 98,651,108)) # P2 Inside # End of Drawing Pot # #=============================================================== #=============================================================== # # ErrorInput : # * size = 18 (motors) * 3 (errors/motors) # * ErrorInput[i][0]=1 => Mechanical failure # * ErrorInput[i][1]=1 => Cable Failure # * ErrorInput[i][2]=1 => Driver Failure ErrorInput=[] # End of ErrorInput # #=============================================================== #=============================================================== # # TestOneMotor : # * size = 18 # * TestOneMotor[i]=1 => The datas (position and speed) # can be send to the motor i when the user press # the button 'RUN' # * TestOneMotor[i]=0 => The datas (Position and Speed) # can't be send to the motor TestOneMotor=[] # End of TestOneMotor # #=============================================================== #=============================================================== # # OutputRM : # * size = Number of Rack Monitor x 2 # * This array has the words sent to each motor # # Example: # OutputRM[2][0] = 111 -> put the word 111 to the Channel P08 of the Rack Monitor CTL_RM_02-03 # OutputRM[2][1] = 101 -> put the word 101 to the Channel P02 of the Rack Monitor CTL_RM_02-03 OutputRM=[] # End of OutputRM # #=============================================================== #=============================================================== # # InputRM : # * size = Number of Rack Monitor x 2 # # Example: # InputRM[2][0] = 111 -> get the word 111 to the Channel P03 of the Rack Monitor CTL_RM_02-03 # InputRM[2][1] = 101 -> get the word 101 to the Channel P07 of the Rack Monitor CTL_RM_02-03 InputRM = [] # End of InputRM # #=============================================================== #=============================================================== # # LVDTRM : # * size = Number of Rack Monitor x 4 # # Example: # InputRM[2][0] = 111 -> get the word 111 to the Channel 32 of the Rack Monitor CTL_RM_02-03 # InputRM[2][1] = 703 -> get the word 703 to the Channel 33 of the Rack Monitor CTL_RM_02-03 # InputRM[2][3] = 354 -> get the word 354 to the Channel 34 of the Rack Monitor CTL_RM_02-03 # InputRM[2][4] = 265 -> get the word 265 to the Channel 35 of the Rack Monitor CTL_RM_02-03 LVDTRM = [] # Initialisation LVDTRM (P10 channel 32 to 35) # End of LVDTRM # #=============================================================== #=============================================================== # # HomeLVDT : # * size = 18 # * LVDT value when the motors are in Home Position HomeLVDT=[] # End of HomeLVDT # #=============================================================== tempo_mechanical_error = [] #=============================================================== # # Canvas Class # class CanvasDisplay: def __init__(self,parent): self.display=Canvas(parent,width=640,height=480,relief=GROOVE,bd=4) self.item=[] self.beam=[] for i in range(len(DrPot)): self.item.insert(i,self.display.create_rectangle(DrPot[i][0],DrPot[i][1],DrPot[i][2],DrPot[i][3],fill='red',outline='black')) for i in range(30): self.beam.insert(i*2,self.display.create_polygon(7+i*12,389-i*6,13+i*12,386-i*6,16+i*12,392-i*6,14+i*12,398-i*6,8+i*12,401-i*6,10+i*12,395-i*6,fill='blue')) self.beam.insert(i*2+1,self.display.create_polygon(13+i*12,386-i*6,19+i*12,383-i*6,22+i*12,389-i*6,20+i*12,395-i*6,14+i*12,398-i*6,16+i*12,392-i*6,fill='black')) for j in range(30,45): i=j-30 self.beam.insert(i*2,self.display.create_polygon(631-i*12,77+i*6,637-i*12,74+i*6,634-i*12,80+i*6,636-i*12,86+i*6,630-i*12,89+i*6,628-i*12,83+i*6,fill='brown')) self.beam.insert(i*2+1,self.display.create_polygon(625-i*12,80+i*6,631-i*12,77+i*6,628-i*12,83+i*6,630-i*12,89+i*6,624-i*12,92+i*6,622-i*12,86+i*6,fill='black')) self.display.create_text(410,195,text='D0') self.display.bind("",self.ChoicePot) self.display.pack(side=TOP) self.NumInput = 0 self.beam_color=0 return def update(self): # for i in range(20): # if self.beam_color == 0: # self.display.itemconfigure(self.beam[i*2],fill='blue') # self.display.itemconfigure(self.beam[i*2+1],fill='black') # self.display.itemconfigure(self.beam[20+i*2],fill='brown') #7 self.display.itemconfigure(self.beam[20+i*2+1],fill='black') # else: # self.display.itemconfigure(self.beam[i*2],fill='black') # self.display.itemconfigure(self.beam[i*2+1],fill='blue') # self.display.itemconfigure(self.beam[20+i*2],fill='black') # self.display.itemconfigure(self.beam[20+i*2+1],fill='brown') # if self.beam_color==0: # self.beam_color=1 # else: # self.beam_color=0 for i in range(len(Pot)): if Pot[i][7]>10: NumRM = Pot[i][7] - 7 else: NumRM = Pot[i][7] - 1 if ErrorRM[NumRM] == 0: val=float(LVDTRM[NumRM][Pot[i][8]-32]) else: val=0 if (Pot[i][1]=='Top'): x=0 y=(0.0048828125*val + 10)*1.5 elif (Pot[i][1]=='Bottom'): x=0 y=-(0.0048828125*val + 10)*1.5 elif (Pot[i][1]=='Inside'): x=-(0.0048828125*val + 10)*1.5 y=0 else: x=(0.0048828125*val + 10)*1.5 y=0 self.display.coords(self.item[i],DrPot[i][0]+x,DrPot[i][1]+y,DrPot[i][2]+x,DrPot[i][3]+y) if ErrorInput[i] != [0,0,0]: color='red' else: if TestOneMotor[i].get() == 1: color='green' else: color='orange' self.display.itemconfigure(self.item[i],fill=color,outline='black') return self.NumInput def ChoicePot(self,event): try: tag=self.display.find_withtag('current')[0]-1 except: return if tag",self.__b1Callback) self.__NewPos.bind('', self.__LockValue) self.__NewPos.bind('', self.__UnlockValue) self.__NewPos.bind('',self.__NewValue) self.__NewPos.grid(row=0, column=1, sticky=W) l = Label(f,text='Speed :',font=("Times",12)).grid(row=1, column=0, sticky=W) self.__SpeedIndex=IntVar() self.__SpeedChoice=StringVar() b=OptionMenu(f,self.__SpeedChoice, "0") b.config(relief=GROOVE,font=("Times",12)) b.grid(row=1, column=1, sticky=W) m = Menu(b) m.add_radiobutton(label=self.__SpeedParams[0],variable=self.__SpeedIndex, value=0,command=self.__SpeedSet,font=("Times",12)) m.add_radiobutton(label=self.__SpeedParams[1],variable=self.__SpeedIndex, value=1,command=self.__SpeedSet,font=("Times",12)) self.__SpeedLabel = b self.__SpeedMenu = m b['menu'] = m f.pack() f = Frame(self,relief=GROOVE) b = Button(f,text='Run',command=self.Run,font=("Times",12)) b.pack(side=LEFT,expand=YES) b = Button(f,text='Stop',command=self.StopMotor,font=("Times",12)) b.pack(side=RIGHT,expand=YES) f.pack(side=TOP,expand=YES,fill=X) f = Frame(self,relief=GROOVE) b = Button(f,text='Home',command=self.Home,font=("Times",12)) b.pack() self.__HomeButton=b f.pack(side=TOP,expand=YES,fill=X) return def __SpeedSet(self): MenuChoice = self.__SpeedIndex.get() self.__SpeedChoice.set(self.__SpeedParams[MenuChoice]) return def StopMotor(self): word = 0 val = word & 0xffff for i in range(len(Pot)): if int(Pot[i][4]) < 10: NumRM = int(Pot[i][4])-1 else: NumRM = int(Pot[i][4])-7 OutputRM[NumRM][Pot[i][3]]= val print Pot[i][4] self.HomePosition = 0 return def Run(self): try: float(self.NewPosition) except: if (self.NewPosition == ''): text = 'You must enter a position' else: text = 'The new position must be a number.' Dialog(self, title = 'Error', text = text, bitmap = 'error', strings= ('OK',), default = 0) self.NewPosition = '' self.__NewPos.delete(0,'end') return if (float(self.NewPosition)*120 > 8160): Dialog(self, title = 'Error', text = 'New position > 68 mm', bitmap = 'error', strings= ('OK',), default = 0) return if (float(self.NewPosition) < 0): Dialog(self, title = 'Error', text = 'New position < 0', bitmap = 'error', strings= ('OK',), default = 0) return if self.HomePosition == 1: word=int(self.HomePosition * 32768 + self.__SpeedIndex.get()*16384) else: word =int ( self.__SpeedIndex.get()*16384 + 8192 + float(self.NewPosition)*1000*3/25) if (self.NewPosition == '0'): text = 'Home Position' else: text = 'New Position : ' + chr(13) + ' %d half turns' %(float(self.NewPosition)*120) + chr(13) + ' %6.2f mm' %(float(self.NewPosition)) + chr(13) for i in range(len(Pot)): if TestOneMotor[i].get() == 1: text=text + chr(13) + ' ' + Pot[i][0] + ' ' + Pot[i][1] ans = Dialog(self, title = 'New Position', text = text,anchor=W, bitmap = 'question', strings=('YES','NO'),default=0) if ans.num == 0: for i in range(len(Pot)): if TestOneMotor[i].get() == 1: val=word & 0xffff if ErrorInput[i] == [0,0,0]: if int(Pot[i][4]) < 10: NumRM = int(Pot[i][4])-1 else: NumRM = int(Pot[i][4])-7 OutputRM[NumRM][Pot[i][3]]= val print val self.HomePosition = 0 return def Home(self): self.HomePosition=1 self.NewPosition = '0' self.Run() return def destroy(self): Frame.destroy(self) return def update(self): for i in range(len(Pot)): if int(Pot[i][4]) < 10: NumRM = int(Pot[i][4])-1 else: NumRM = int(Pot[i][4])-7 wanted=(OutputRM[NumRM][Pot[i][3]] & 8191)*25/3000 val=((0.0048828125*float(LVDTRM[NumRM][Pot[i][8]-32])+10)*2-HomeLVDT[i])*33.5/24 if ((abs(wanted-val) < 0.5) & ((OutputRM[NumRM][Pot[i][3]] & 16384) == 16384)) == 1: OutputRM[NumRM][Pot[i][3]]=OutputRM[NumRM][Pot[i][3]]-16384 class ChoiceMotorFrame(Frame): def __init__(self,parent): Frame.__init__(self,parent,relief=GROOVE,bd=4) self.textButton=StringVar() self.textButton.set("Run") self.__CreateFrame() return def __CreateFrame(self): f = Frame(self) f.pack(side=TOP,fill=X) Label(f,text='D2 :',font=("Times",12)).grid(row=0, column=0, sticky=W) Label(f,text='Inside :',font=("Times",12)).grid(row=0, column=1, sticky=W) self.D1I= Checkbutton(f,variable=TestOneMotor[0], selectcolor='green').grid(row=0, column=2, sticky=W) Label(f,text='D1 :',font=("Times",12)).grid(row=1, column=0, sticky=W) Label(f,text='Inside :',font=("Times",12)).grid(row=1, column=1, sticky=W) self.D2I= Checkbutton(f,variable=TestOneMotor[1], selectcolor='green').grid(row=1, column=2, sticky=W) Label(f,text='A2 :',font=("Times",12)).grid(row=2, column=0, sticky=W) Label(f,text='Top :',font=("Times",12)).grid(row=2, column=1, sticky=W) self.A2T= Checkbutton(f,variable=TestOneMotor[2], selectcolor='green').grid(row=2, column=2, sticky=W) Label(f,text='Bottom :',font=("Times",12)).grid(row=3, column=1, sticky=W) self.A2B= Checkbutton(f,variable=TestOneMotor[3], selectcolor='green').grid(row=3, column=2, sticky=W) Label(f,text='Outside :',font=("Times",12)).grid(row=4, column=1, sticky=W) self.A2O= Checkbutton(f,variable=TestOneMotor[4], selectcolor='green').grid(row=4, column=2, sticky=W) Label(f,text='Inside :',font=("Times",12)).grid(row=5, column=1, sticky=W) self.A2I= Checkbutton(f,variable=TestOneMotor[5], selectcolor='green').grid(row=5, column=2, sticky=W) Label(f,text='A1 :',font=("Times",12)).grid(row=6, column=0, sticky=W) Label(f,text='Top :',font=("Times",12)).grid(row=6, column=1, sticky=W) self.A1T= Checkbutton(f,variable=TestOneMotor[6], selectcolor='green').grid(row=6, column=2, sticky=W) Label(f,text='Bottom :',font=("Times",12)).grid(row=7, column=1, sticky=W) self.A1B= Checkbutton(f,variable=TestOneMotor[7], selectcolor='green').grid(row=7, column=2, sticky=W) Label(f,text='Outside :',font=("Times",12)).grid(row=8, column=1, sticky=W) self.A1O= Checkbutton(f,variable=TestOneMotor[8], selectcolor='green').grid(row=8, column=2, sticky=W) Label(f,text='Inside :',font=("Times",12)).grid(row=9, column=1, sticky=W) self.A1I= Checkbutton(f,variable=TestOneMotor[9], selectcolor='green').grid(row=9, column=2, sticky=W) Label(f,text='P1 :',font=("Times",12)).grid(row=10, column=0, sticky=W) Label(f,text='Top :',font=("Times",12)).grid(row=10, column=1, sticky=W) self.D1T= Checkbutton(f,variable=TestOneMotor[10], selectcolor='green').grid(row=10, column=2, sticky=W) Label(f,text='Bottom :',font=("Times",12)).grid(row=11, column=1, sticky=W) self.D1B= Checkbutton(f,variable=TestOneMotor[11], selectcolor='green').grid(row=11, column=2, sticky=W) Label(f,text='Outside :',font=("Times",12)).grid(row=12, column=1, sticky=W) self.D1O= Checkbutton(f,variable=TestOneMotor[12], selectcolor='green').grid(row=12, column=2, sticky=W) Label(f,text='Inside :',font=("Times",12)).grid(row=13, column=1, sticky=W) self.D1I= Checkbutton(f,variable=TestOneMotor[13], selectcolor='green').grid(row=13, column=2, sticky=W) Label(f,text='P2 :',font=("Times",12)).grid(row=14, column=0, sticky=W) Label(f,text='Top :',font=("Times",12)).grid(row=14, column=1, sticky=W) self.D2T= Checkbutton(f,variable=TestOneMotor[14], selectcolor='green').grid(row=14, column=2, sticky=W) Label(f,text='Bottom :',font=("Times",12)).grid(row=15, column=1, sticky=W) self.D2B= Checkbutton(f,variable=TestOneMotor[15], selectcolor='green').grid(row=15, column=2, sticky=W) Label(f,text='Outside :',font=("Times",12)).grid(row=16, column=1, sticky=W) self.D2O= Checkbutton(f,variable=TestOneMotor[16], selectcolor='green').grid(row=16, column=2, sticky=W) Label(f,text='Inside :',font=("Times",12)).grid(row=17, column=1, sticky=W) self.D2I= Checkbutton(f,variable=TestOneMotor[17], selectcolor='green').grid(row=17, column=2, sticky=W) return class MenuFrame(Frame): def __init__(self, parent,quitCallback=None): Frame.__init__(self,parent,relief=GROOVE,bd=4) self.__CreateFrame(quitCallback) return def __CreateFrame(self,quitCallback): f = Frame(self) f.pack(side=TOP,fill=X) m = self.__actionMenu(self,quitCallback) m.pack(side=LEFT) m = self.__helpMenu(self) m.pack(side=RIGHT) return def destroy(self): Frame.destroy(self) return def __actionMenu(self, parent, quitCallback): b = Menubutton(parent, text='Actions', underline=0, relief=GROOVE) m = Menu(b) m.add_command(label='Configuration',command= self.__configmotor,font=("Times",12)) m.add_command(label='Quit', command=quit,font=("Times",12)) b['menu'] = m return b def __configmotor(self): ConfigMotorFrame(self) return def __helpMenu(self, parent): b = Menubutton(parent, text='Help', underline=0, relief=GROOVE) m = Menu(b) m.add_command(label='Help', command=self.__help,font=("Times",12)) b['menu'] = m return b def __help(self): Dialog(self, title = 'FPD V4.0', text = '"The Gods help those who help themselves"', bitmap= 'error', default=0, strings=('OK',)) return class InfoMotorFrame(Frame): def __init__(self,parent): Frame.__init__(self,parent) self.__CreateFrame() return def __CreateFrame(self): f = Frame(self) f.pack(side=TOP,expand=YES,fill=X) self.__inputFrame = InputFrame(self) self.__inputFrame.pack(side=TOP, fill=X, expand=YES) def update(self, NumInput = None): self.__inputFrame.update(NumInput) class StatusRackMonitor: def __init__(self,parent): for i in range(len(RackMonitor)): OutputRM.insert(i,[0,0]) # Initialisation OutputRM (P08, P02) InputRM.insert(i,[0,0]) # Initialisation InputRM (P03, P07) LVDTRM.insert(i,[0,0,0,0]) # Initialisation LVDTRM (P10 channel 32 to 35) ErrorRM.insert(i,0) # Initialisation ErrorRM def update(self): self.__DSTAT=CaChannel() self.__BIN00=CaChannel() self.__BIN01=CaChannel() self.__BIN02=CaChannel() self.__BIN03=CaChannel() self.__AD=CaChannel() for i in range(len(RackMonitor)): try: self.__DSTAT.searchw(RackMonitor[i] + '.DSTAT') d=self.__DSTAT.getw() except: d=9999 if (d != 0): ErrorRM[i]=1 else: ErrorRM[i]=0 try: self.__BIN00.searchw(RackMonitor[i] + '.BIN00') InputRM[i][0]=self.__BIN00.getw() except: pass try: self.__BIN03.searchw(RackMonitor[i] + '.BIN03') InputRM[i][1]=self.__BIN03.getw() except: pass try: self.__BIN01.searchw(RackMonitor[i] + '.BIN01') self.__BIN01.putw(OutputRM[i][0]) except: pass try: self.__BIN02.searchw(RackMonitor[i] + '.BIN02') self.__BIN02.putw(OutputRM[i][1]) except: pass try: self.__AD.searchw(RackMonitor[i] + '.AD') LVDTRM[i]=[self.__AD.getw()[32],self.__self.__AD.getw()[33],self.__AD.getw()[34],self.__AD.getw()[35]] except: pass del self.__BIN00 del self.__BIN01 del self.__BIN02 del self.__BIN03 del self.__AD del self.__DSTAT del d class IOFrame(Frame): def __init__(self,parent): Frame.__init__(self,parent) self.__CreateFrame() return def __CreateFrame(self): f = Frame(self) f.pack(side=TOP,expand=YES,fill=X) self.__outputFrame = OutputFrame(self) self.__outputFrame.pack(side=TOP, fill=X, expand=YES) self.__choicemotorFrame = ChoiceMotorFrame(self) self.__choicemotorFrame.pack(side=TOP, fill=X, expand=YES) def update(self, NumInput = None): self.__outputFrame.update() class RmMotorFrame(Frame): def __init__(self, parent): Frame.__init__(self, parent) # Initialize the base class title = 'FPD V4.0 - CTL_RM_02' self.master.title(title) try: self.__createFrames(self) # Create component frames except: self.destroy() raise return def destroy(self): Frame.destroy(self) return def __createFrames(self, parent): self.__statusRackMonitor = StatusRackMonitor(self) self.__errorFrame = ErrorFrame(self) self.__MenuFrame = MenuFrame(parent) self.__MenuFrame.pack(side=TOP, fill=X) self.__ioframe = IOFrame(parent) self.__ioframe.pack(side=LEFT, fill=X) self.__infomotorframe = InfoMotorFrame(parent) self.__infomotorframe.pack(side=RIGHT, fill=X) self.__canvasdisplay = CanvasDisplay(parent) return def update(self): self.__statusRackMonitor.update() self.__errorFrame.update() Num_Input = self.__canvasdisplay.update() self.__ioframe.update(Num_Input) self.__infomotorframe.update(Num_Input) return def quit(): global rmFrame, menuBar text='Are you sure you want to quit?' + chr(13) for i in range(len(Pot)): if int(Pot[i][4]) < 10: NumRM = int(Pot[i][4])-1 else: NumRM = int(Pot[i][4])-7 if Pot[i][6] == 0: InputData=InputRM[NumRM][Pot[i][5]] & 0x007f else: InputData=(InputRM[NumRM][Pot[i][5]] & 0x3f80) / 0x007f if ((InputData & 0x0002) != 2): text=text+'The Detector '+ Pot[i][0]+ ' ' + Pot[i][1] + ' is not in Home Position.' + chr(13) ans = Dialog(title = 'Exit', text = text,font=("Times",12), bitmap = 'question', strings = ('Yes','No',),default = 0) if ans.num == 0: frame.destroy() exit() return # Integrated test procedure if (__name__== '__main__'): from sys import * UpdatePeriod = 1000 # 1 second def update(): global frame frame.update() frame.after(UpdatePeriod, update) return global frame base = Tk() try: frame = RmMotorFrame(base) except: print 'Error Accessing Power PC: CTL_RM_02 (D0OLCTL02)' exit() frame.pack(fill=X, expand=YES,ipadx=0,ipady=0) # Pack into topmost widget text= 'Last Version : FPD V 3.5, October, 12 2000' + chr(13) + chr(13) text= text + 'Modifications :' + chr(13) text= text + ' * Now, you must enter the distance in millimiters between the home position and the wanted position' + chr(13) text= text + ' * One label "Position Wanted" is added' + chr(13) text= text + ' * The Current Position indicates the distance in millimeters between the Home Position and the current position' + chr(13) + chr(13) text= text + ' All comments are welcome' + chr(13) text= text + ' Lionel Peyrichoux (peyricli@fnal.gov)' Dialog(base, title = 'FPD V 4.0', text = text,font=("Times",12), bitmap= 'warning', default=0, strings=('OK',)) update() base.mainloop()