Objektorientiertes Programmieren in der Automatisierungstechnik

Ingenieure von heute, die eine moderne Hochsprache wie C++, Java oder C# kennen, sind es gewohnt, dass sie sich um den Aufbau des geräteinternen Speichers nicht kümmern müssen. Das Anlegen von Datenstrukturen, Arrays oder eben von Objekten ist bei modernen Hochsprachen eine Selbstverständlichkeit und bei heutigen komplexeren Automatisierungslösungen geradezu ein Muss, um lesbare und wartbare Programme erstellen zu können. JetSym STX ermöglicht die Verwendung dieses in der Hochsprachen- und PC-Programmierung längst etablierten Paradigmas auch für Automatisierungslösungen. Obgleich der Anwender nicht gezwungen ist, sie schon jetzt zu nutzen, wird sich die objektorientierte Programmierung zweifelsohne auch in der Automatisierung durchsetzen. Wann verwendet man objektorientierte Programmierung? Letztlich entscheidet der Programmierer selbst, welche Funktionen er in Form von Klassen zusammenfassen möchte. Hauptkriterien sind die Wiederverwendbarkeit und die Vererbung. So macht es Sinn, gleichartige Teile einer Maschine (Achsen, Ventile, Zylinder) in Form von Klassen zu beschreiben und entsprechend viele Instanzen davon anzulegen. Durch die damit einhergehende Kapselung reduziert sich auch die Fehleranfälligkeit – wird ein Fehler einmal behoben, so wirkt sich das gleich auf alle Instanzen aus. Klassische Anwendungsbeispiele für Objekte in der Automatisierung sind beispielsweise: – Regleralgorithmen – Logbuchverwaltung – Beschreibung konkreter Hardware wie Drehtische, Pumpen, Mischer, usw. – Abstraktion von Schnittstellen (z.B. Datenaustausch mit Visualisierung) – Abstraktion von Bedienfunktionen Klassen sind also Beschreibungen des Verhaltens von Objekten, wie z.B. eine Klasse \’Achse\‘. Eine Achse ist in der Lage von A nach B zu fahren. Das Verhalten einer Servo-, einer Schrittmotor- oder einer Hydraulikachse bei Positionierungen ist jedoch unterschiedlich. In diesem Fall leitet der Programmierer je eine Klasse \’Servoachse\‘, \’Schrittmotorachse\‘ und \’Hydraulikachse\‘ von der Basisklasse \’Achse\‘ ab. Bei der Verwendung in einer Applikation wird das Objekt mit der gewünschten Klasse instanziiert und die Hardware-Adresse übergeben. Intuitive Eingabe reduziert Fehler Wie hilfreich objektorientierte Programmierung ist, zeigt beispielsweise der Objektaufruf einer Achse, da es sich bei den Methoden um die Abstraktion von möglichen Prozeduren handelt. Ist eine Achse als Einzelantrieb oder Verbund mit anderen Antrieben als Klasse angelegt und die dazugehörenden Methoden definiert, ergibt sich durch die Punktschreibweise für den Programmierer eine vereinfachte und intuitive Eingabe, da jeweils nur die Methoden aufgerufen werden können, die für das jeweilige Achsobjekt auch möglich sind. Beispiele sind Aufrufe wie \’axVertikal.MoveHome.SetReference(0)\‘ oder \’axGripper.MovePtP.Position(200)\‘. Ein weiteres Beispiel einer Klasse zeigt Bild 1 für ein Valve-Objekt. Die Deklaration der Klasse wird mit dem Schlüsselwort \’class\‘ eingeleitet. Verschiedene Methoden, wie zum Beispiel die Grundstellungsfahrt, werden in der Klasse deklariert. Eine Methode ist vergleichbar mit einer Funktion oder einem Unterprogramm mit dem Unterschied, dass eine Klasse beliebig viele Methoden enthalten kann. Mit den Schlüsselwörtern \’public\‘, \’protected\‘ und \’private\‘ wird deklariert, ob ein Member oder eine Methode in weiteren Objekten verwendet werden darf. Die Instanziierung der Klasse zu Objekten zeigt Bild 2. Die Klassen-Deklaration ist vergleichbar mit einem Bauplan. Ein Objekt selbst entsteht erst durch Instanziierung, also der Deklaration einer Variablen einer Klasse. Variablen einer Klasse werden deshalb auch Instanzen genannt. Es können beliebig viele Instanzen einer Klasse angelegt werden, dabei erhält jede Instanz einen eigenen Satz von Eigenschaften. Der Objektaufruf mit den deklarierten Methoden im Programmcode selbst wird in Bild 3 gezeigt. Die Programme werden durch die Verwendung der objektorientierten Programmierung sehr kompakt und einfach lesbar. Was bedeutet objektorientiertes Programmieren? Ein objektorientiertes Programm besteht aus einer strukturierten Menge von Objekten. Der Vorteil eines Objektes ist der, dass es eine in sich abgeschlossene Einheit von Daten und Algorithmen darstellt. Der Programmierer bestimmt während der Designphase, welche Methoden und Daten von außen sichtbar (public) sind und welche nur innerhalb der Klasse (private) verwendet werden dürfen. Eine Klasse im Sinne der objektorientierten Programmierung ist die Verbindung und Kapselung einer Datenstruktur mit den Funktionen oder Unterprogrammen, die auf dieser Datenstruktur mit dem Ziel einer besseren Wiederverwendbarkeit operieren. Bei der Verwendung im Programm werden dann Objektinstanzen (konkrete Variablen) dieser Klasse angelegt. Am ehesten lässt sich eine Klasse noch mit einem Funktionsblock aus der klassischen SPS-Programmierung (IEC 61131-3) vergleichen. Während ein Funktionsblock jedoch nur eine Funktion besitzt, die den Zustand des Funktionsblocks beeinflusst, kann eine Klasse beliebig viele Funktionen besitzen. Die Funktionen und Unterprogramme einer Klasse werden als Methoden bezeichnet. Der spezielle Name erklärt sich daher, dass Methoden implizit Zugriff auf alle Eigenschaften, also die Daten, ihrer Klasse haben. Methoden sind also Funktionen, die einen \’unsichtbaren\‘ Parameter – die aktuelle Instanz – übergeben bekommen. Die Konsequenz für den Anwender ist, dass Daten und Programmcode eine logische Einheit bilden und der Programmierer darüber entscheidet, auf welche Weise man auf sie zugreift und welche Daten von außen verändert werden können. Daten können also nicht quer über das Programm hinweg beschreiben werden, wenn das nicht so gewollt ist. Diese Kapselung von Daten und Methoden führt zu einer erheblichen Fehlerreduzierung. Vererbung von Klassen Darüber hinaus können Klassen auch Eigenschaften und Methoden anderer Klassen übernehmen und diese erweitern – dieser Vorgang wird als Vererbung bezeichnet. Gerade dieses Grundprinzip der objektorientierten Programmierung ist für die Automatisierungstechnik hochinteressant. Einzelne Teile einer Anlage, wie z.B. eine Achse, ein Drehtisch oder eine Pumpe, können nun als Software-Objekte im Steuerungsprogramm 1:1 abgebildet werden. Das führt schon durch die intuitive Schreibweise, wie Achse.MoveTo(…) oder Valve.Open zu besonders gut lesbaren Programmen. Nicht zuletzt verringern sich durch die Kapselung aber auch die Entwicklungs- und die Inbetriebnahmezeit, und es vereinfacht sich natürlich entsprechend die Wartung der Programme. Virtuals, Properties und Interfaces Für virtuelle Methoden speichert der Compiler nicht die Adresse der Methode aus dem Arbeitsspeicher in dem jeweiligen Objekt, sondern er verwaltet virtuelle Methoden in einer separaten Tabelle (VMT – Virtual Method Table). Im Objekt wird lediglich die Adresse dieser Tabelle gespeichert. Der Compiler sorgt dafür, dass bei der Ausführung des Programms für jede Klasse eine eigene Tabelle im Speicher angelegt wird. Alle virtuellen Methoden dieser Klasse werden darin, zusammen mit ihren Adressen, eingetragen. Der Aufruf einer virtuellen Methode führt dann über die Tabelle immer zur richtigen Methode der konkreten Instanz. Das funktioniert auch dann, wenn die Methode über einen Zeiger auf die Instanz aufgerufen wird (Polymorphie). Diese Aufrufart wird auch als \’späte Bindung\‘ bezeichnet, weil das Programm erst zur Laufzeit die Adresse der Methode ermittelt. JetSym STX bietet zur Deklaration das Schlüsselwort \’virtual\‘ an. Als Properties werden \’intelligente\‘ Member einer Klasse bezeichnet. Jeweils für den Lese- und den Schreibzugriff auf ein Property kann eine separate Methode angegeben werden, die in demselben Moment ausgeführt werden soll. Damit lassen sich sehr elegant Bereichsprüfungen oder auch sofortige Reaktionen programmieren. JetSym STX unterstützt darüber hinaus auch Index-Properties, die sich quasi wie intelligente Arrays verhalten. Die Deklaration erfolgt über das Schlüsselwort \’property\‘. Mit Hilfe des Schlüsselworts \’Interface\‘ werden gemeinsame Methoden definiert, die dann in verschiedenen Klassen implementiert werden. Das ist insbesondere dann von Bedeutung, wenn die Klassen keine gemeinsame Basisklasse haben. Eine Klasse kann dabei auch mehrere Interfaces implementieren. In dem Fall ersetzen Interfaces das sprachliche Mittel der Mehrfachvererbung Verglichen mit einer Klasse handelt es sich bei einem Interface um eine Art abstrakte Klasse, die Methoden zwar deklariert, aber nicht selbst implementiert. Interfaces selbst können deshalb auch nicht instanziiert werden. Es ist aber möglich, Variablen von einem Interface-Typ anzulegen. Diese Variablen verhalten sich dann wie Referenz-Variablen und müssen eine konkrete Instanz zugewiesen bekommen. Eine Interface-Variable kann jede Instanz jeder Klasse referenzieren, sofern dieses Interface sie auch implementiert hat. Der Kundennutzen Für langjährig erfahrene SPS-Programmierer, die mit den klassischen SPS-Sprachen vertraut sind, sind die Vorteile vielleicht nicht sofort ersichtlich, weil sie sie über all die Jahre nicht vermisst haben. Die objektorientierte Programmierung erfordert einen anderen Denkansatz, und es soll an dieser Stelle nochmals darauf hingewiesen werden, dass die objektorientierte Programmierung bei JetSym STX kein Muss ist. Dennoch wird sich in Zukunft auch in der Automatisierungswelt wie in der PC-Welt die objektorientierte Programmierung vor allem bei komplexeren Projekten durchsetzen. Wenn ein Unternehmen auf die Bedürfnisse seiner Kunden schnell, flexibel und effizient reagieren will, ermöglicht die Verwendung von Objekten und Klassen eine rasche – und vor allem durch die Kapselung eine stark fehlerreduzierte Variante – der Integration von Programmteilen. Zum Zweiten werden umfangreiche und komplexe Programme kompakter und deshalb besser lesbar. Dadurch werden wiederum die Entwicklungs- und Inbetriebnahmezeiten deutlich reduziert. In der Automation einzigartig Dieser Beitrag zur objektorientierten Programmierung bildet den Abschluss der dreiteiligen Reihe über JetSym STX. Dennoch ist es aufgrund es Funktionsumfangs von JetSym STX nicht möglich, alle Features, die Tool und Sprache bieten, detailliert zu beleuchten. So gibt es weitere komfortable Befehle und Funktionalitäten für – Makros – IT-Funktionalitäten, z.B. E-Mails versenden – Netzwerkhandling – Strukturierte Ausnahmebehandlung – Motion (Achssynchronisation)