Technische Dokumentation
2.2 Implementation der CAN-Kommunikation
2.2.1 Einbinden eines neuen CAN-Gerätes
2.2.2 Einbinden des zweiten CAN-Busses
2.3 Die Low-Level Hardware-Treiber
3.1.1 Ergänzung zum Setzen neuer Zielkoordinaten
3.3 Regelmäßige Wartungsaufgaben
3.3.1 Beobachtungsparameter einstellen
3.3.2 Schaltsekunden: Neue SLALIB-Version
3.4 Organisation der HoLiCS-Dateien
3.4.1 Neue Dateien und Verzeichnisse hinzufügen
3.8 Automatische Dokumentationsgenerierung (Doxygen)
3.10 Verwendete Bibliotheken 19
3.11 Konfiguration der Lenze-Servoumrichter 20
3.12 Kalibration der Motor-Koordinaten 20
Die Software des Systems ist in C/C++ geschrieben und läuft auf einem Pentium-PC unter Linux, der mit CAN-Bus- und Winkelencoder-Interfacekarten sowie einer Funkuhrenkarte ausgerüstet ist.
Im folgenden werden die einzelnen Software-Module vor allem im Hinblick
auf ihr Zusammenwirken besprochen; die aus speziell formatierten Quelltext-Kommentaren
erzeugte Referenz-Dokumentation ist auf dem Entwicklungsrechner
verfügbar unter file:///HOLICS/src/backend/doc/doxygen/html/index.html
.
Im wesentlichen besteht die Software des Steuerungssystems aus einem
monolithischen Programm (namens backend
1 ), welches als einzelner Prozeß (single threaded) ausgeführt
wird. Innerhalb dieses Prozesses erfolgt sowohl die astronomische Positionsberechnung,
die Hardware-Ansteuerung, als auch die Interaktion mit dem Benutzer.Das
Steuerprogramm ist weitgehend nach objektorientierten Grundsätzen
entworfen worden
2 . Die bereits vorhandenen oder an Linux angepaßten Hardware-Treiber
sind durch Wrapper-Klassen gekapselt worden, um die Handhabung zu vereinfachen
und die Übersichtlichkeit des Systems zu erhöhen.
Nachfolgend wird zunächst ein Überblick über die Klassenstruktur gegeben und die prinzipielle Funktionsweise des Systems anhand des Zusammenspiels der wichtigsten Klassen erläutert. Insbesondere wird der Ablauf der CAN-Kommunikation dargestellt , da diesem Punkt im Hinblick auf hardwareseitige Erweiterungen (Handset, Kuppel-, Fokussteuerung) besondere Bedeutung zukommt. Schließlich folgen einige Informationen zu den Hardware-Treibern.
Die „Schaltzentrale“ ist die Klasse Telescope. Sie beinhaltet die zentrale Steuerschleife control_loop() und ist damit für die Koordination und Ablaufsteuerung des gesamten Systems verantwortlich. Des weiteren übernimmt sie die astronomische Positionsberechnung 4 . Sehr eng mit ihr verwoben 5 ist die Klasse TelescopeViewController. Sie ist für die Benutzerschnittstelle zuständig, d. h. sie zeigt den Systemzustand auf dem Bildschirm an und nimmt Eingaben des Benutzers entgegen.
Auf der rechten Seite des Diagramms befinden sich die für die CAN-Kommunikation verantwortlichen Klassen. Im Hinblick auf CAN-basierte Hardware-Erweiterungen ist hier zunächst die Vererbungsstruktur dieser Klassen wesentlich: LenzeMotor (z. Zt. die einzige konkrete Implementierung eines CAN-Gerätes) erbt von CANopen_Device , das wiederum von CAN_Device abgeleitet ist (beides abstrakte Basis-Klassen 6 ). Nach diesem Schema können auch weitere CAN- bzw. CANopen-Geräte in das System integriert werden.
Für jede physisch vorhandene Geräteart existiert in der Software eine entsprechende Klasse - und für jedes Gerät ein Objekt (eine Instanz) der jeweiligen Klasse (DCFClock, HeidenhainEncoder , LenzeMotor, CAN_Controller). Teilweise sind diese konkreten Geräteklassen von abstrakten Basisklassen abgeleitet, die die Schnittstellen definieren bzw. grundlegende Funktionen für die abgeleiteten Klassen bereitstellen (z. B. Encoder, CAN_Device , CANopen_Device).
Daneben existieren noch Hilfsklassen, z. B. ein PID-Controller sowie austauschbare Pointing-Modelle.
Die *_Exception-Klassen dienen zur strukturierten Fehlerbehandlung. So kann z. B. eine Timeout-Bedingung in einem umgebenden try...catch -Block abgefangen und bearbeitet werden (siehe z. B. TelescopeViewController::updateScreen() ).
Anmerkung: Die Stereotypen „Publisher“ bzw. „Subscriber“ bei CAN_Controller und CANopen_Device weisen darauf hin, daß das Zusammenspiel dieser Klassen dem „Publisher-Subscriber-Muster“ folgt, siehe z. B. [4], [2].
Darin werden nacheinander die Positionsberechnung durchgeführt, die aktuelle Position gemessen, die Bildschirmanzeige aktualisiert, anstehende CAN-Nachrichten verarbeitet, die Motoren gesteuert und schließlich Tastatureingaben verarbeitet.
Die folgende Grafik zeigt noch einmal die Geräte-Klassen und -Objekte,
mit denen die Telescope-Klasse direkt kooperiert:
Abbildung 1
Abbildung 1: Kollaboratoren
der Telescope-Klasse.
Die Beschriftungen
der gestrichelten Beziehungs-Pfeile geben die Instanz-Variablen an, über
die der Zugriff auf das entsprechende Objekt der angegebenen Klasse erfolgt.
Die unbeschrifteten, durchgezogenenen Pfeile stellen die Vererbungsbeziehungen
dar.
Die Kommunikation der Telescope-Klasse mit allen Kollaboratoren läuft synchron ab, d. h. mittels normaler Funktions- bzw. Methodenaufrufe. Daher darf die gesamte Laufzeit aller aufgerufenen Methoden nicht über der Periodendauer der Steuerschleife liegen.
Im folgenden wird gezeigt, wie die die Kommunikation über den CAN-Bus in die Steuerschleife integriert ist.
Ein Objekt der Klasse CAN_Controller kümmert sich um Empfang und Versand von Nachrichten über den physischen CAN-Bus. Bei jedem Aufruf der dispatch()-Methode wird geprüft, ob beim physischen CAN-Controller neue Nachrichten (Klasse: CAN_Message ) eingegangen sind. Falls ja, werden sie dort abgeholt und an die Geräte-Objekte verteilt, die sich für den Empfang von Nachrichten mit der entsprechenden ID angemeldet haben, indem deren receive()-Methode mit der Nachricht als Parameter aufgerufen wird.
Welche Nachrichten (IDs) die Geräte-Objekte empfangen wollen, teilen sie dem CAN_Controller-Objekt mit Hilfe der subscribe() -Methode mit. Diese kann z. B. im Konstruktor des Geräte-Objektes aufgerufen werden. (Eine Nachricht kann also auch von mehreren Geräten empfangen werden.) Über die unsubscribe()-Methode können sich die Geräte-Objekte auch wieder beim CAN-Controller abmelden. Dies geschieht übrigens automatisch im Destruktor von CAN_Device , so daß davon abgeleitete Klassen sich nicht darum kümmern müssen.
Für das Senden von Nachrichten zum CAN-Bus stellt die Geräte-Oberklasse CAN_Device die send()-Methode bereit. Diese reicht die Nachricht an das zu dem Geräte-Objekt gehörige CAN_Controller-Objekt weiter, das sie schließlich an die Hardware sendet.
Zur Fehlerbehandlung: Falls die Nachricht nicht abgesetzt werden konnte (z. B. wegen eines Bus-Fehlers), wird eine CAN_Send_Exception geworfen.
Implementieren der receive()-Methode, um eingehende CAN-Messages empfangen zu können.
Im Steuerprogramm ein Objekt der neuen Klasse instanziieren (z. B. im Hauptprogramm oder im Konstruktor der Telescope -Klasse).
Natürlich muß nun noch regelmäßig (z. B. in Telescope::control_loop() ) die dispatch()-Methode des neuen Controller-Objektes aufgerufen werden, um eventuell über den CAN-Bus empfangene Nachrichten an die Geräte-Objekte weiterzureichen.
Sollen an diesem Bus CANOpen-Geräte betrieben werden, muß zudem regelmäßig die sendSync()-Methode aufgerufen werden, um die für die PDO-Kommunikation erforderliche Synchronisation sicherzustellen.
Da es wesentlich weniger Aufwand bedeutet, die Hardware direkt aus dem Steuerprogramm heraus anzusprechen, als vollständige Linux-Gerätetreiber für den Kernel-Modus zu erstellen, werden die meisten Geräte auf diese Weise angesteuert 7 . Eine Ausnahme bildet das CAN-Interface. Hierfür stand bereits ein fertiger Linux-Gerätetreiber zur Verfügung.
Für Implementierungsdetails der Low-Level-Treiber sei auf die Hardware-Dokumentation der Hersteller bzw. die im Quelltext mitgelieferten Treiberprogramme verwiesen. Für den Betrieb unter Linux wurde hier nur die Syntax der Port-I/O-Funktionen angepaßt.
Da einige Abläufe beim Hardware-Zugriff zeitkritisch sind (insbesondere die I2C-Bus-Ansteuerung bei der Initialisierung der Heidenhain-Encoder), funktioniert die Hardware-Steuerung aus dem User-Mode in diesen Fällen nur dann zuverlässig, wenn der POSIX-Real-Time-Scheduler von Linux mit der SCHED_FIFO Scheduling Policy eingesetzt wird. Dabei läuft die Zeitscheibe des betroffenen Prozesses nur dann ab, wenn dieser blockierend wartet (z. B. bei Ein-/Ausgaben) oder ein höher priorisierter Real-Time-Prozeß lauffähig wird. Der Prozeß wird allerdings immer noch vom Kernel zur Bearbeitung von Interrupts unterbrochen. Das läßt sich nur im Kernel-Mode verhindern. Details zum Scheduler finden sich in [3], weitere Informationen zur Hardware-Ansteuerung unter Linux in [5] und [1].
Da einige Abläufe in diesem Treiber (insbesondere bei der I 2C-Bus-Kommunikation während der Initialisierung) zeitkritisch sind, ist er nur unter dem SCHED_FIFO-Scheduler lauffähig.
Dieser Treiber stellt zwei Devices zur Verfügung: /dev/can0, /dev/can1
Auf diese Devices wird mittels normaler Datei-Ein/Ausgabe-Befehle zugegriffen, um CAN-Messages zu senden bzw. zu empfangen. Die Messages selbst müssen dafür allerdings im SJA-1000-spezifischen Binärformat vorliegen (siehe http://www.semiconductors.com/pip/SJA1000/N1 ).
Auf diesem Treiber setzt die CAN_Controller-Klasse auf, um die CAN-Kommunikation
zu vereinfachen.
Zielpositionen lassen sich im Encoder-System angeben, indem den Koordinaten der Buchstabe „E“ vorangestellt wird:
E <deg_HA> <min_HA> <sec_HA> <deg_DEC> <min_DEC> <sec_DEC>
Die Koordinaten werden für beide Achsen im Bogenmaß angegeben.
Achtung: Im Encoder-System eingegebene Zielkoordinaten werden nicht auf Zulässigkeit geprüft – Man kann das Teleskop so also leicht in die Endschalter fahren!
Einige Parameter können noch nicht über die Benutzerschnittstelle interaktiv gesetzt werden. Diese müssen von Hand in der Datei „ Observation.dat“ eingetragen werden.
Diese Parameter sind: Die atmosphärischen Bedingungen (Druck, Temperatur, rel. Luftfeuchte), beobachtete Wellenlänge und DUT, die Zeitdifferenz zwischen UT und UTC (siehe Diplomarbeit). Normalerweise müssen diese Parameter nur für Beobachtungen mit besonderen Anforderungen an die Positionsgenauigkeit (z. B. Langzeit-Aufnahmen in Horizontnähe oder Pointingmessungen) genau eingestellt werden; am kritischsten ist noch der Luftdruck, da sich die Refraktion proportional dazu verhält. Im Normalfall liegt die erreichbare Nachführpräzision auch ohne angepaßte Parameter deutlich über der des alten Systems. Ideal wäre natürlich eine on-line-Kopplung an eine elektronische Wetterstation.
Achtung: Die Zuordnung der Parameter erfolgt z. Zt. nur über ihre Position in der Datei. Daher sind Unstimmigkeiten zwischen Dokumentation und Quelltext sehr leicht möglich!
Reihenfolge und Einheiten der Parameter:
Die Dokumentation zum Gesamtsystem findet sich unter /HOLICS/doc ,
die Referenzdokumentation zum Hauptprogramm „backend“ unter /HOLICS/src/doc/backend/doxygen.
Die Quelltextdateien sind den Aufgaben nach in verschiedenen Verzeichnissen
unterhalb von /HOLICS/src abgelegt:
|
Hauptprogramm, Initialisierung, Utilities |
|
Teleskopsteuerung |
|
CAN-Bus Ansteuerung |
|
Motorsteuerung |
|
Encoder-Ansteuerung |
|
Low-Level Hardware-Treiber |
|
|
|
Treiber-Klasse für Hopf-Funkuhr |
|
|
|
Adaptierte DOS-Treiber für Heidenhain-Encoder |
|
|
|
(nur Daten-Files von Lenze, keine Treiber) |
|
SLALIB - Positionsastronomische Routinensammlung |
|
TPM - Positionsastronomische Routinensammlung |
|
Hilfs-Routinen (libgpl, ...) |
Starten des Source Navigators:
snavigator /HOLICS/src/backend/backend.proj
Der Name der Projektdatei kann auch entfallen; dann wird eine Auswahlliste der zuletzt bearbeiteten Projekte angezeigt.
Ein neues Executable läßt sich durch einen Aufruf von
make
Die Referenz-Dokumentation wird erst durch einen Aufruf von
make doc
Der Window-Manager auf dem Datenaufnahme-PC im Rechnerraum von Turm 6 ist so konfiguriert, daß unter dem Menüpunkt „Astro“ das Executable ausgeführt wird, welches sich unter
/HOLICS/src/backend.working/backend
befindet.
Daher muß das entstandene Programm nach dem Test noch dorthin kopiert – und mit den notwendigen root-Rechten ausgestattet – werden. Dazu sind folgende Schritte nötig (als root):
cd /HOLICS/src/backend
cp backend ../backend.working
cd ../backend.working
Achtung: Die verwendeten Bibliotheken (slalib, tpm, ...) werden bei diesem Vorgehen nicht neu übersetzt. Falls dies aus irgendeinem Grund nötig sein sollte (z. B. zur Fehlerbeseitigung), muß die jeweilige Bibliothek entsprechend der zugehörigen Dokumentation übersetzt werden. Danach muß das Steuerprogramm wie beschrieben neu übersetzt bzw. gelinkt werden.
Zur Zeit befindet sich das aktuelle Repository auf dem UPC81 unter
/home/ccd/CVSROOT.
Dort ist sowohl das Format der Quelltextmarkierungen als auch der Aufbau der Konfigurationsdatei "Doxyfile" beschrieben.
Die erzeugte Dokumentation kann in verschiedenen Formaten ausgegeben werden, u. a. HTML, Unix man-pages, RTF, LaTeX.
Zum Aktualisieren der Dokumentation siehe Abschnitt "Build-Prozeß (make)" .
Das
System wurde bisher mit den Kernel-Versionen 2.0.36 und 2.2.10 unter
SuSE-Linux 6.2 getestet.
Bibliotheken
Die benötigten Bibliotheken werden im nächsten Abschnitt einzeln besprochen.
Von der C++-Standardbibliothek werden unter anderem die Containerklassen
der STL genutzt. Informationen hierzu finden sich in [6] sowie online unter
http://www-europe.sgi.com/Technology/STL
.
Die SLALIB ist eine Routinensammlung zur Positionsastronomie, die
von Patrick Wallace am RAL entwickelt wurde. Sie wird bereits seit Jahren
in Steuerungssystemen an großen Observatorien erfolgreich eingesetzt.
P. Wallace hat uns freundlicherweise die C-Version für den Einsatz
in HoLiCS zur Verfügung gestellt.
Online-Dokumentation: http://www.starlink.rl.ac.uk/star/docs/sun67.htx/sun67.html
lokal: file:///HOLICS/src/slalib/sun67.htx/sun67.html
Um einen möglichst gleichmäßigen Rundlauf zu erhalten, wird (wie von Lenze vorgeschlagen) die Grundkonfiguration „Leitfrequenzkaskade / Master“ eingesetzt,
da in dieser Konfiguration der Winkelregler aktiv ist.
Die verwendeten Steuerungsparameter (z. B. Proportionalfaktor des Winkelreglers) sind in einer relativ frühen Phase des HoLiCS-Projektes durch Ausprobieren (über manuelle Parameteränderungen am Bedienfeld) ermittelt worden. Mit Hilfe ausführlicher programmgesteuerter Meßreihen dürften daher noch Optimierungen möglich sein. (Ähnliches gilt aufgrund der wechselseitigen Beeinflussung damit auch für die Parameter der von Telescope::control_loop() verwendeten PID-Controller.) Möglicherweise ist es auch erforderlich, einige Parameter, wie z. B. den maximal zulässigen Motor-Strom, dynamisch anzupassen, um z. B. Anlaufschwierigkeiten bei kaltem Wetter bzw. Schwingungsneigung bei warmem Wetter zu vermeiden.
Kopien der aktuellen Parametersätze sind in den Hand-Bedien-Einheiten sowie auf dem BUSCA-Notebook gespeichert.
Um den Nullpunkt des internen Koordinatensystemn der Lenze-Motorsteuerungen mit dem der Teleskopachsen (Heidenhain-Encoder) abzugleichen, muß man – so lange noch keine automatische Kalibration implementiert ist – wie folgt vorgehen:
Voraussetzung für das folgende Vorgehen ist, daß die Heidenhain-Encoder kalibriert sind, d. h. der Zähler-Anteil der gemessenen Koordinaten null ist, wenn die Encoder auf der Referenzmarke stehen 9 .
Zunächst fährt man das Teleskop so, daß die Heidenhain-Encoder auf ihrer jeweiligen Referenzmarke stehen:
Danach kann das Teleskop wieder wie gewohnt
betrieben werden.
[1] Beck, Michael et al., Linux-Kernelprogrammierung, 1998
[2] Buschmann, Frank et al., Pattern-Orientierte Softwareentwicklung, 1998
[3] Gallmeister, Bill, Programming for the real world, 1995
[4] Gamma, Erich, et al., Entwurfsmuster, 1996
[5] Rubini, Alessandro, Linux Gerätetreiber, 1998
[6]
Stroustrup, Bjarne, Die C++-Programmiersprache, 2000
Stichwortverzeichnis
CAN
Interface 12
SJA-1000 12
control_loop() 6
CTASSERT 19
cvs 16, 18
Doxyfile 16ff
Doxygen 18
Encoder-System 13
Kalibration 20
Kernel 18
LIBGPL 19
make 17
make
Makefile 16
NCURSES 19
Real-Time
POSIX-Real-Time-Scheduler 11
SCHED_FIFO 11
REF-Block 21
Referenz-Dokumentation 4
Referenzmarke 21
REF-MARK 21
Schaltsekunde 15
SLALIB 19
STL 19
Telescope-Klasse 6
TelescopeViewController-Klasse 7
TPM
19
Ursprünglich war eine Aufteilung des Systems in Back-End (für Positionsastronomie und Hardware-Ansteuerung) sowie (evtl. mehrere) Front-Ends (für die Benutzer-Interaktion bzw. für Batch-Steuerung) geplant (daher auch der Name des Executables). Im Zuge einer möglichen Erweiterung des Systems um eine graphische Benutzerschnittstelle wäre es sicher sinnvoll, diese Aufteilung nachträglich vorzunehmen, um mehrere GUIs gleichzeitig an verschiedenen Orten ablaufen lassen zu können - zumindest im Anzeige-Betrieb (z. B. Haupt-Haus, Rechnerraum und evtl. Kuppel - bzw. sogar entfernt in Bonn für Wartungs- oder Diagnosezwecke).
Bedingt durch die Entwicklungshistorie ist die Objektorientierung nicht überall konsequent durchgehalten worden. Ein konsequent objektorientiertes Redesign der betroffenen Stellen dürfte Verständlichkeit und Robustheit des Systems deutlich verbessern.
Unified Modeling Language - näheres z. B. unter http://www.rational.com/uml
Im Hinblick auf eine bessere „Separation of Concerns“ (um das System einfacher und verständlicher zu machen) sollte diese Funktionalität möglichst ausgelagert werden.
TelescopeViewController ist als „friend“ von Telescope deklariert, hat also Zugriff auf dessen private Elemente. Dies rührt daher, daß sie aus der Aufteilung der Telescope-Klasse entstanden ist. Diese enge Kopplung sollte nach Möglichkeit bei einer zukünftigen Bearbeitung des Quelltextes aufgehoben werden, um die Robustheit des Systems zu erhöhen.
Näheres zu abstrakten Basisklassen siehe [6].
Dieses Vorgehen hat den Nachteil, daß man nicht ohne das Steuerprogramm auf die Geräte zugreifen kann; insbesondere kann man die Standard-Unix-Tools nicht für Debugging- oder Konfigurations-Zwecke einsetzen.
Eine einfache Möglichkeit, eine bessere, sicherere und bedienerfreundlichere Verwaltung der Konfigurationsdateien (z. B. im .INI-Format) zu realisieren, bietet die „parsecfg“-Bibliothek von Yuuki NINOMIYA ( http://www.enjoy.ne.jp/~gm/program/parsecfg/ ).
Wie man diese Kalibration durchführt, ist in der Kurzanleitung beschrieben (Referenzmarken bei eingeschalteter Referenzmarken-Suche überfahren). Sollten die Koordinatensysteme jemals so weit voneinander abweichen, daß dieses Verfahren nicht praktikabel ist, muß man die Referenzmarken-Suche starten und die Motoren manuell steuern (z. B. mit Hilfe des Global-Drive-Control-Programmes von Lenze), um die Referenzmarken zu überfahren.
P. Hirsch - (Version: 13.09.2001,Henning Poschmann)