HSG |
|
Die Klasse 'Aufzug' stellt ein einfaches Bildschirmmodell eines Aufzugs zwischen zwei Stockwerken dar. Es werden drei Callbacks cbTaste, cbOben, cbUnten zur Verfügung gestellt, die jeweils bei der Betätigung eines der drei Taster ausgelöst werden. Der Aufzugsmotor kann über die Methode setZustand in die Zustände 'auf', 'ab' und 'stopp' versetzt werden. Das Programm aufzug0.py dient dem Test der Klasse und stellt zusätzlich eine Fernbedienung RC zur Verfügung.
Was ist an aufzug1.py schlechter als an aufzug0.py? Schaue dir jeweils die Systemauslastung an.
Erstelle ein Klassendiagramm als Schnittstellenbeschreibung (Schnittstelle etymologisch, wikipedia) der Klasse 'Aufzug'.
Erstelle und teste zu dem 'Software-Aufzug' aus aufzug0.py eine Steuerung.
Zur Ermittlung der Zustände könnte man der Frage "Was macht der Aufzug gerade?" nachgehen. In einem Zustandsdiagramm kann ein erster Ablauf modelliert werden.
self.zustaende = ('steht unten','fährt aufwärts','steht oben','fährt abwärts','Fehler') self.eingaben = ('eUnten','eOben','eTaste') self.ausgaben = ('auf','ab','stopp')
Überträgt man die bisherigen Informationen in eine Automatentafel ein, so fallen die vielen Lücken auf.
Z ↓ / E → | 0 | 1 | 2 |
0 | 1 / 0 | ||
1 | 2 / 2 | ||
2 | 3 / 1 | ||
3 | 0 / 2 |
Eine Lücke in der Tafel bedeutet, es gibt eine Zustands-Eingabe-Kombination, für die der Automat 'nicht weiß, was er tun soll'. Man könnte sich überlegen, die Situation zunächst zu retten, indem man einen Fehlerzustand 4 einführt. Beim Übergang in den Fehlerzustand wird man den Motor sicherheitshalber abschalten. Die neue Automatentafel sieht dann so aus:
Z ↓ / E → | 0 | 1 | 2 |
0 | 4 / 2 | 4 / 2 | 1 / 0 |
1 | 4 / 2 | 2 / 2 | 4 / 2 |
2 | 4 / 2 | 4 / 2 | 3 / 1 |
3 | 0 / 2 | 4 / 2 | 4 / 2 |
4 | 4 / 2 | 4 / 2 | 4 / 2 |
Die Steuerung sieht dann so aus:
class Steuerung(object): def __init__(self): self.zustaende = ('steht unten','fährt aufwärts','steht oben','fährt abwärts','Fehler') self.eingaben = ('eUnten','eOben','eTaste') self.ausgaben = ('auf','ab','stopp') self.f = (((4,2),(4,2),(1,0)), ((4,2),(2,2),(4,2)), ((4,2),(4,2),(3,1)), ((0,2),(4,2),(4,2)), ((4,2),(4,2),(4,2))) self.zustand = 0 self.ausgabe = None self.eingabe = None def verarbeiteEingabe(self,eingabe): self.eingabe = eingabe (self.zustand,self.ausgabe) = self.f[self.zustand][self.eingabe] if self.zustand == 4: print('Fehler!')
Der Fehlerzustand wird über die Konsole signalisiert. Klar, dass eigentlich kein Fehler passieren sollte.
Um die Steuerung mit dem Aufzug zu verbinden, muss der Controller dafür sorgen, dass die Callbacks (Ereignisse) cbUnten, cbOben und cbTaste die entsprechenden Eingaben in die Steuerung bewirken und dass die Ausgabe der Steuerung an den Auzug weitergeleitet wird.
class Controller(object): def __init__(self): self.steuer = Steuerung() self.aufzug = Aufzug(self.cbOben,self.cbUnten,self.cbTaste) self.aufzug.mainloop() def cbUnten(self): self.steuer.verarbeiteEingabe(0) self.aufzug.setZustand(self.steuer.ausgabe) def cbOben(self): self.steuer.verarbeiteEingabe(1) self.aufzug.setZustand(self.steuer.ausgabe) def cbTaste(self,event): self.steuer.verarbeiteEingabe(2) self.aufzug.setZustand(self.steuer.ausgabe)
Erste Tests mit aufzugAutomat0.py verlaufen positiv. Drückt man jedoch während einer Aufzugsbewegung den Taster, wird ein Fehler ausgelöst. Doch gut, dass wir zunächst in einer Simulation testen! Der Automat muss modifiziert werden:
Der Aufzug funktioniert nun bereits ganz ordentlich (aufzugAutomat.py).
Es fehlt aber noch ein entscheidendes Stück Praxistauglichkeit. Wir gingen bisher davon aus, dass der - reale - Aufzug genau wie der Automat zu Beginn im Zustand 'steht unten' ist. Was ist aber, wenn z.B. der Aufzug nach einem Stromausfall auf halbem Weg stehenbleibt? Nun, man müsste in einer Referenzfahrt zunächst mal für eine definierte Ausgangslage sorgen. Diese Referenzfahrt kann entfallen, wenn der Aufzug bereits richtig steht. Im Automatenmodell benötigen wir sogenannte bedingte Übergänge (guarded transitions), die nur durchgeführt werden, wenn die Bedingung [in eckigen Klammern] erfüllt ist.
Programm aufzugAutomat2.py verwirklicht die Referenzfahrt. Wie testet man die Praxistauglichkeit ab? Für die Referenzfahrt wurde der Automat nicht angetastet, sondern der zusätzliche Code in den Controller verlegt. Ist das gut oder böse?
Warum würde wohl ein Benutzer während der Aufzugsfahrt die Taste drücken? Was würde er sich wünschen? Erstelle ein erweitertes Zustandsdiagramm und verbessere deine Steuerung.
Modellierung des Aufzugs am HSG?
Im Programm aufzugInterface2.py wird über die serielle Schnittstelle mit der identischen Steuerung ein realer Aufzug gesteuert. Der Aufzugsmotor wird dabei über eine H-Brücke mit externer Energie versorgt. Weiter unten mehr dazu!
Die Schaltungsidee ist einem Artikel von Clemens Valens aus elektor 3/2009 entnommen.