Über die Komplexität von Systemen
Heute ist Sonntag. Wie immer scheint die Sonne, es ist kalt draußen, und es gibt Frühstück bis 9:30 Uhr. Da ich gestern so viel gegessen habe, lasse ich das Frühstück ausfallen und gehe direkt ins Labor. Bei drei fleischlastigen Mahlzeiten am Tag muss man aufpassen, dass man nicht zu viel zunimmt. Zumindest ich, der die meiste Zeit im warmen B2-Labor verbringt. Bei den Leuten, die draußen arbeiten, ist das etwas anderes. In der Kälte kann der Körper schon einmal doppelt so viel Kalorien verbrennen.
Sonntag ist der freie Tag auf der Station und somit haben auch die Schreiner frei, die ich für die Installation der Bleche in der Teleskop-Box benötige. Daher widme ich mich heute der Software. Wir verwenden zur Steuerung und Datenerfassung unseres Lidars einen Linux-Computer. Ich habe über die letzten Tage Updates heruntergeladen und installiert; das Betriebssystem (Debian) ist damit auf dem neuesten Stand. Nun gilt es, unsere Lidar-Software zu aktualisieren. Es ist ein modulares System. Jede Hardwarekomponenten (z.B. Photonenzähler, Laser, Spiegelsteuerung, …) ist softwaretechnisch über ein eigenständiges Programm implementiert. Alle Programme docken sich an einen zentralen Router an, über den sie untereinander Informationen und Daten austauschen können. Das hört sich erst einmal kompliziert an, hat aber einen entscheidenden Vorteil. Wenn man etwas an einer Hardwarekomponente oder deren Software ändert, muss man nur diesen Teil neu testen und validieren. Hätten wir ein einziges Programm, welches alle Hardware bedient und die gesamte Funktionalität vereint, dann wäre das Programm komplex und kaum handhabbar.
Ein Schaubild zur Klassifizierung von Systemen aus einem meiner Vorträge. Bei der Entwicklung unserer Lidar-Software sind wir dem roten Pfeil gefolgt.
Was ist Komplexität bei Systemen? Man kann sich das anhand von einem einfachen Schaubild klarmachen. Auf der horizontalen Achse haben wir die Anzahl der Subsysteme und auf der vertikalen Achse die Kompliziertheit eines Subsystems, die nach oben zunimmt. Fangen wir links unten an: wenig kompliziert und eine geringe Zahl von Subsystemen. Das wäre ein einfaches System. Wenn wir nach oben gehen, dann sind die Subsystem kompliziert – haben zum Beispiel einen großen Funktionsumfang, aber wir haben immer noch eine geringe Anzahl an Subsystemen. Man kann diese Art von System ein kompliziertes System nennen. Rechts unten haben wir eine hohe Anzahl von Subsystemen geringer Kompliziertheit. Man nennt dies ein dynamisches System. Wenn nun zu der hohen Anzahl an Subsystemen noch eine große Kompliziertheit der einzelnen Subsysteme kommt, dann landen wir bei einem komplexen System. Das sollte man vermeiden, denn komplexe Systeme sind schwer zu implementieren, schwer zu testen, schwer zu debuggen und versagen letztendlich oft. Um von komplexen Systemen wegzugkommen, geht man häufig den Weg, dass man ein kompliziertes Subsystem, beispielsweise die Steuerung des Lidars, in mehrere kleine Subsysteme aufteilt, die man dann jeweils einzeln einfacher handhaben kann. Genau diesen Weg sind wir auch bei der Entwicklung der Lidar-Software gegangen. Wir haben eine große Anzahl von Subsystemen, in unsrem Fall separate Programme, die sich an den Hardwarekomponenten orientieren. Jedes Programm hat für sich gesehen einen geringen und begrenzten Funktionsumfang und kann daher viel leichter entwickelt und getestet werden.
Heute widme ich mich dem Programm, welches die Verbindung zum Photonenzähler herstellt. In unserem Lidar werden von der Atmosphäre rückgestreute Lichtteilchen (Photon) des Laserstrahl mit einem Teleskop aufgefangen und einem Detektor zugeleitet. Der Detektor detektiert das Lichtteilchen und sendet einen elektrischen Impuls an den Photonenzähler. Bei dem Photonenzähler handelt es sich im Grunde um eine hochgenaue Uhr, die bei jedem ausgehenden Laserpuls neu gestartet wird. Erhält der Photonenzähler nun einen elektrischen Impuls von einem Detektor, so merkt sich der Zähler den Stand der Uhr und der Zeitstempel wird in einen Datenpuffer geschrieben. Das passiert für jedes detektierte Lichtteilchen. Über die Lauftzeit der Lichtteilchen können wir später die Höhe berechnen, in der das Lichtteilchen gestreut wurde. Die Software für den Photonenzähler liest die internen Datenpuffer aus, decodiert die Zeitstempel und sortiert sie nach Detektorkanälen und Laserpulsen. Im normalen Betrieb werden etwa eine Million solcher Zeitstempel pro Sekunde verarbeitet, in Pakete gepackt und an das nächste Subsystem, die Datenerfassung des Lidars, weitergeleitet.
Der Photonenzähler ist die weiße Box in der Mitte des Bildes. Die Kabel leiten die elektrischen Signal von den optischen Detektoren zum Zähler.
Mit dem Update des Betriebssystems und des Hardwaretreibes für den Photonenzähler hat sich die Softwareschnittstelle, über die ich auf die Datenpuffer des Photonenzählers zugreifen kann, geändert. Früher verwendeten wir ein spezielles Kernel-Modul für die Kommunikation mit der Hardware. Um davon wegzukommen, implementiere ich eine neue, auf libusb basierende Schnittstelle. Im Grunde sind das nicht viele Zeilen an Code, die hinzugefügt oder gelöscht bzw. geändert werden müssen. Aber der Teufel steckt wie immer im Detail. Bestimmte Variablen, welche den Photonenzähler konfigurieren, haben plötzlich eine leicht andere Bedeutung. Dann finde ich noch einen Fehler in der Hardware des Zählers. Manchmal stehen korrupte Zeitstempel mit unsinnig hohen Werten in den Datenpuffern. Da diese jedoch nur beim Zurücksetzen der Uhr auftreten, kann ich die fehlerhaften Zeitstempel relative einfach identifizieren und herausfiltern.
Es ist kurz vor Mitternacht, als die neue Software das erste Mal fehlerfrei durchläuft. Ich schreibe noch diesen Bericht und gehe dann zufrieden ins Bett.