Module Controller
[hide private]
[frames] | no frames]

Source Code for Module Controller

  1  #Controller.py 
  2  #A class which create a MealyMachine from a deterministic controller 
  3  #and then create its PLC Code (ST language) 
  4  #Author: Matteo Cantarelli 
  5  #E-mail: matteo.cantarelli@lurpa.ens-cachan.fr 
  6  #Release: 0.2.2 
  7   
  8  import Automata 
  9   
 10  TAB='\t'    #The standard indentetion 
 11   
12 -class CMealyMachine(object):
13 """A Class to create a Mealy machine Controller from a DFA Controller. 14 The method L{CMealyMachine.getPLCCode} exploits the Mealy machine in order to produce the PLC control program.""" 15
16 - def __init__(self,controller):
17 """ 18 Creates a Mealy machine Controller from a DFA Controller. 19 20 This constructor builds automatically the Mealy machine. 21 22 @type controller: a L{Automata.CAutomaton} instance 23 @param controller: The DFA Controller which has to be converted into a Mealy machine Controller 24 @return: void 25 """ 26 27 self.__controller=controller 28 self.__sequences={} #the mealy machine is stored under a list of list 29 #every list is composed by the following elements: 30 # Begin_State - Uncontrollable event - Controllable events - Arrival_State 31 32 states=set([controller.getInitialStates()[0]]) #it initially contains the only initial state of the controller 33 done=set() #the set of already processed states 34 35 while (len(states)): 36 newstates=set() 37 38 for s in states: 39 stateseq=[] 40 self.__sequences[s.name]=stateseq 41 42 for t in s.getTransitions(): 43 if (not controller.getEvent(t).isControllable()): #checks if the event is uncontrollable 44 mealyset=[t] #add the Begin_State and the uncontrollable event 45 s.getTransitions()[t].getMealyList(mealyset) #getMealyList looks for controllable events and Arrival_State 46 47 stateseq.append(mealyset) #appends the new discovered sequence to the list of sequences 48 49 for x in mealyset: 50 if isinstance(x,Automata.CAutomaton._CAutomaton__CState): #the element is a class and it is not the current state -> it is the arrival state 51 if x.name not in self.__sequences: 52 newstates.add(x) 53 states=newstates
54
55 - def __processState(self,s):
56 return s.lstrip('q')
57
58 - def __processInput(self,i):
59 if i.find('_1')!=-1: 60 return i.rstrip('_1') 61 elif i.find('_0')!=-1: 62 return 'NOT '+i.rstrip('_0') 63 return i
64
65 - def __processOutput(self,o):
66 if o.find('_1')!=-1: 67 a='SET '+ o.rstrip('_1')+';\n' 68 return a 69 elif o.find('_0')!=-1: 70 a='RESET '+o.rstrip('_0')+';\n' 71 return a 72 return o
73
74 - def getMealyAutomaton(self):
75 """ 76 Returns the Mealy machine represented as an Automaton. 77 78 @return: a L{Automata.CAutomaton} instance 79 """ 80 ma=Automata.CAutomaton('Mealy Machine','0','A Mealy Machine representing a deterministic controller') 81 ids=0 #id state 82 ide=0 #id event 83 for state,seq in self.__sequences.iteritems(): 84 newstate=ma.addState(str(ids),state,'',state=='q0',False) 85 for s in seq: 86 s.reverse() 87 ce=s.pop() 88 eventchain='' 89 parenthesis=True 90 while not isinstance(ce,Automata.CAutomaton._CAutomaton__CState): 91 eventchain=eventchain+ce+',' 92 if parenthesis: 93 eventchain=eventchain+'{' 94 parenthesis=False 95 ce=s.pop() 96 eventchain=eventchain.rstrip(',') 97 eventchain=eventchain+'}' 98 99 ma.addEvent(str(ide),eventchain,'',True) 100 newstate._CState__transitions[eventchain]=ce.name 101 ide+=1 102 ids+=1 103 104 for state in ma.getStates(): 105 for t in state.getTransitions(): 106 state._CState__transitions[t]=ma.getState(state._CState__transitions[t]) 107 return ma
108 109
110 - def getPLCCode(self,filename):
111 """ 112 Write the PLC control program in ST language to the specified filename. 113 114 The Mealy machine is processed in order to produce the code. 115 116 @type filename: string 117 @param filename: the output file path where to write the code 118 @return: void 119 """ 120 121 EXTIF='IF (STATE=' 122 123 f=open(filename, 'w') 124 f.write('PROGRAM\n\n') 125 outevents=set() #a set to store the output events, used to manage the urgence stop 126 for state,seq in self.__sequences.iteritems(): 127 f.write('(*PHRASE*)\n') 128 f.write(EXTIF+self.__processState(state)+') THEN\n') 129 INTIF='IF (' 130 for s in seq: 131 s.reverse() 132 f.write(TAB+INTIF+self.__processInput(s.pop())+') THEN\n') 133 INTIF='ELSIF (' 134 ce=s.pop() 135 while not isinstance(ce,Automata.CAutomaton._CAutomaton__CState): 136 outevents.add(ce.rstrip('_10')) 137 f.write(TAB+TAB+self.__processOutput(ce)) 138 ce=s.pop() 139 f.write(TAB+TAB+'NEXTSTATE:='+self.__processState(ce.getName())+';\n') 140 f.write(TAB+'END_IF;\n') 141 f.write('END_IF;\n') 142 f.write('(*END_PHRASE*)\n\n') 143 f.write('(*PHRASE*)\n') 144 f.write('STATE:=NEXTSTATE;\n') 145 f.write('(*END_PHRASE*)\n\n') 146 f.write('(*PHRASE*)\n') 147 f.write('IF ( S1pb_emergency OR S2pb_emergency OR S3pb_emergency OR S4pb_emergency ) THEN\n') 148 f.write(TAB+'STATE:=0;\n') 149 for oe in outevents: 150 f.write(TAB+'RESET '+oe+';\n') 151 f.write('END_IF;\n') 152 f.write('(*END_PHRASE*)\n') 153 f.write('\nEND_PROGRAM\n') 154 f.write('[EOF]') 155 f.close()
156