Streckeneditor
Die Dokumentation gliedert sich in folgende Abschnitte:
Einleitung
Beim Streckeneditor handelt es sich um ein grafisches Front-End zur Definition
von Streckenverläufen, die den Weg des Fahrzeugs in realen Umgebungen
darstellen. Es können beliebig viele Strecken verwaltet werden, wodurch
sich das Fahrzeug komfortabel an verschiedene Umgebungen anpassen läßt.
Durch die Version 1.0 des Streckeneditors wurde ein Programm ersetzt,
mit dem bisher die einzelnen Streckenparameter in einer Schleife abgefragt
und nach Beenden der Schleife an die Steuerhardware übertragen wurden.
Dieses Programm diente lediglich zu Testzwecken und besaß eine einfache
textuelle Benutzeroberfläche.
Um ein benutzerfreundliches Interface zur Verfügung zu stellen, wurden
folgende Anforderungen an den Streckeneditor gestellt:
All diese Anforderungen konnten in der Version 1.0 des Streckeneditors
realisiert werden.
Das Programm wurde mit dem GNU C++ Compiler in der Version 2.7 erstellt.
Um die Fensterverwaltungsfunktionen und die Grafikoperationen nicht von
Grund auf selbst programmieren zu müssen wurde LEDA ab der Version
3.2.3 verwendet (siehe LEDA
Ressourcen im Internet).
Die Streckeneingabe unterliegt der Einschränkung, daß sich immer
ein Kurvensegment und ein Geradensegment abwechseln müssen. Diese
Bedingung wurde aufgrund von technischen Überlegungen aufgestellt,
da es mit einem Fahrzeug nicht möglich ist auf plötzliche Richtungsänderungen
"unmittelbar" zu reagieren. An einer Stelle, an der 2 Geradensegmente
miteinander verbunden sind, müßte der Fahrzeugrechner die Kreisbahn
interpolieren. Um Fehler durch die Interpolation zu vermeiden, wurde der
Ansatz gewählt eine Richtungsänderung immer durch ein Kurvensegment
zu definieren. Es hätte zwar die Möglichkeit bestanden, ein Kurvensegment
für den Schnittpunkt zweier Geradensegmente vom Editor berechnen und
zeichnen zu lassen, doch hätte dies die Programmierung des Editors
komplexer gemacht, da eine spezielle Behandlung beim Editieren der Strecke
nötig geworden wäre.
Als erstes wird also der Startpunkt der Strecke festgelegt, es folgt
ein Geradensegment und darauf ein Kurvensegment. Die beiden letzten Segmenttypen
wiederholen sich anschließend bis die Eingabe beendet wird. Das Geradensegment
ist dabei immer eine Tangente an den letzten Kreis, das Kurvensegment immer
ein Kreis, der die letzte Gerade als Tangente hat, wobei die Kurvenrichtung
durch die Lage des Mauszeigers in Bezug auf die zuvor gezeichnete Gerade
gegeben ist, d.h. liegt der Mauszeiger rechts von der Geraden, dann wird
eine Rechtskurve gezeichnet und umgekehrt.
Die Größe der Zeichenfläche ist relativ und läßt
sich mit einem Faktor beliebig skalieren. Der Skalierungsfaktor wurde auf
cm festgelegt, da in Anbetracht der geringen Geschwindigkeit keine groessere
Einheit und wegen der Breite des Fahrzeugs und des sich damit ergebenden
Wendekreises von ca. 40 cm auch keine kleinere Einheit sinnvoll gewesen
waere.
Der Streckenverlauf kann nach Abschluß der Eingabe in einer Datei
gespeichert werden und bei Bedarf wieder aus dieser geladen werden. Das
Programm merkt sich dabei jeweils den letzten Dateinamen vor seiner Beendigung.
Dieser wird dann beim nächsten Start wieder als Dateiname angeboten.
Der Streckenverlauf kann editiert werden, indem das jeweils letzte Segment
gelöscht wird. Diese Einschränkung ist durch die Tatsache gegeben,
daß der momentane Verlauf von der geometrischen Position aller benachbarten
Segmente abhängt. Eine direkte Verschiebung einer Geraden wuerde eine
Verschiebung der benachbarten Kurven und der daran angrenzenden Geraden
nach sich ziehen. Bei direkter Verschiebung einer Kurve, würden sich
nur die angrenzenden Geraden verändern. Diese Art der Streckenbearbeitung
hätte die Programmierung des Editors wesentlich umfangreicher gemacht,
weshalb in dieser Version schließlich darauf verzichtet wurde.
Bedienung
Nach dem Start präsentiert sich der Streckeneditor als Fenster mit
einer Optionsfläche und der eigentlichen Zeichenfläche. Im Optionsbereich
sind Eingabefelder enthalten, mit denen man Programmoptionen einstellen
kann, sowie Schalter, über die sich bestimmte Funktionen aufrufen
lassen. Der Zeichenbereich hat anfänglich eine quadratische Größe
von 100 * 100. Das Fenster sollte nicht in seiner ursprünglichen Größe
verändert werden, weil LEDA die Zeichenfläche unter Beibehaltung
des Seitenverhältnisses skaliert und dadurch die Zeichnung verzerrt.
- Optionsbereich
- Im Eingabefeld Dateiname
wird der Name der Datei eingetragen, die geladen bzw. unter der der
Streckenverlauf gespeichert werden soll.
- Im Eingabefeld Skalierungsfaktor
(cm)
wird der Faktor in cm eingegeben, um den die Parameter vor der Übertragung
der Steuersoftware zum Fahrzeug skaliert werden sollen. Der Standardwert
beträgt hier 3 cm.
- Im Eingabefeld Geschwindigkeit (km/h)
wird die Geschwindigkeit eingegeben, mit der das Fahrzeug den gezeichneten
Streckenverlauf abfahren soll. Der Standardwert beträgt hier 0,3 km/h.
Der Wert sollte für dieses Fahrzeug im Bereich zwischen 0 und 0,6
km/h liegen.
- Der Schalter Laden
liest einen Streckenverlauf aus der Datei, die durch den Text im Eingabefeld
Dateiname spezifiziert wird, in den Editor und erlaubt die Manipulation
ab dem letzten Segment der Strecke. Nach dem Laden kommt es zu einem kurzen
Flackern des Bildschirms, das dadurch hervorgerufen wird, daß das
Fenster geschlossen und direkt wieder neu geöffnet wird. Nur so gelang
es den Optionsbereich zu aktualisieren, da unter Umständen ein neuer
Skalierungsfaktor, bzw. eine neue Geschwindiwkeit geladen wurde und deshalb
das Eingabefeld neu gesetzt werden muß.
- Der Schalter Speichern
schreibt den Streckenverlauf des Editors in die Datei, die durch den
Text im Eingabefeld Dateiname spezifiziert wird.
- Der Schalter Neu
löscht den aktuellen Fensterinhalt und erlaubt so die vollständige
Neueingabe einer Strecke.
- Der Schalter Transfer
initiiert den Transfer der Streckendaten über die serielle Schnittstelle
zum Steuerungsrechner. Dazu wird eine Batch-Datei aufgerufen, die die Software
kompiliert, den Debugger startet und das Programm transferiert. Dazu muß
das Fahrzeug ueber die serielle Schnittstelle mit dem Host-Rechner verbunden
sein.
- Der Schalter Hilfe
startet Netscape und liest diese Dokumentation in den Browser ein.
- Der Schalter Ende
beendet das Programm und speichert den zur Zeit aktuellen Dateinamen
in der Datei 'editor.ini'.
- Zeichenbereich
Die Eingabe eines Streckenverlaufs startet mit der Festlegung des Ausgangspunktes
der Strecke durch Betätigen der linken Maustaste. Danach wird das
erste Geradensegment eingegeben. Im folgenden Schritt wird der Kurvenradius
und die Richtung der Kurve in Form eines Kreissegments festgelegt. Dabei
ist zu vermerken, dass sich nur Radien größer 20cm eingeben
lassen. Dies ist eine weitere Beschränkung, die vom Fahrzeug vorgegeben
ist, denn um eine Drehung auf der Stelle durchzuführen, die extremste
Form einer Kurve, müßte ein Rad rückwärts bewegt werden
und das ist zur Zeit nicht möglich. Die kleinste Kurve kann also gefahren
werden, wenn ein Rad feststeht. Da das Fahrzeug ca. 20cm breit ist, muß
also ein Mindestradius von 20cm gewählt werden. Die Kurvenrichtung
wird dabei aufgrund der Lage des Mauscursors zum letzten Geradensegment
ermittelt. D.h. befindet der Cursor sich links davon, dann handelt es sich
um eine Linkskurve und umgekehrt. Die nachfolgende Gerade ist die Tangente
an den Kreis, vom Benutzer wird dabei der Austrittswinkel und die Länge
der Tangente eingestellt.
Die beiden letzten Schritte werden ab diesem Punkt ständig wiederholt,
bis der Benutzer den Zeichenmodus beendet, das Programm verläßt
oder den Schalter "Neu" betätigt.
Um einen Abschnitt zu editieren ist es in dieser Version nur möglich,
das jeweils letzte Segment des Streckenverlaufs mit der mittleren Maustaste
zu löschen und anschließend neu zu zeichnen.
Mit der rechten Maustaste kann die Eingabe eines Streckenverlaufs beendet
werden.

Der Dateiname wird beim ersten Start des Editors mit dem Standardwert
"Strecke.lst" initialisiert. Wird der Dateiname vom Benutzer
verändert, dann wird beim nächsten Start dieser Name als Standard-Dateiname
angeboten. Der Name wird in der Datei "editor.ini" abgespeichert.
Ist diese Datei nicht vorhanden, dann wird sie beim Verlassen des Editors
automatisch erzeugt.
Ein Dateiname wird vom Editor nur als gültig erkannt, wenn er die
Endung ".lst" besitzt. Vergißt der Benutzer diese 4 Zeichen
an den Dateinamen anzuhängen, dann wird dies beim Speichern automatisch
vom Programm durchgeführt. Dabei erkennt der Algorithmus aber lediglich
".lst", wenn aber zum Beispiel der Punkt vergessen wurde, dann
wird der Dateiname trotzdem um ".lst" erweitert.
Aufbau
Das Programm ist in C++ geschrieben. Die folgenden Darstellungen basieren
auf der objektorientierten Modellierungsmethode OMT (Object Modelling Technique)
nach Rumbaugh. Das Modell ist jedoch nicht vollständig, es werden
jeweils nur die wichtigsten Teile zum Zwecke der Dokumentation dargestellt.
Objektmodellierung

- CElement
dient als abstrakte Basisklasse und bietet die Funktionalität
zum Einfügung von Elementen in eine doppelt-verkettete Liste. Abstrakt
ist die Klasse aus dem Grund, weil die Funktionen Draw(), Load() und Save()
erst in einer abgeleiteten Klasse implementiert werden müssen, bevor
diese instantiiert werden kann. Diese Konstruktion dient dazu, die Implementation
der drei oben genannten Operationen zwingend vorzuschreiben, bevor die
Klasse benutzt werden kann. Durch Verwendung des virtual-Mechanismus wird
selbst bei Zeigern auf die Basisklasse immer die korrekte Funktion eines
Elements aufgerufen, obwohl der exakte Typ zur Laufzeit nicht bekannt ist.
- CGerade
ist von CElement und von segment abgeleitet, wodurch sich der LEDA-Typ
segment in die Liste CList einfügen läßt.
- CKurve
ist von CElement und von circle abgeleitet, wodurch sich der LEDA-Typ
circle in die Liste CList einfügen läßt.
- CList
speichert Elemente vom Typ CElement und bietet Funktionen zum Anhängen
und Entfernen einzelner Elemente und zum Zeichnen der gesamten Liste in
einem beliebigen Fenster. Hier ist auch die State-Machine implementiert,
die durch Hinzufügen bzw. Entfernen von Streckenelmementen jeweils
ihre Zustände wechselt.
- CEditorWnd
initialisiert ein LEDA-window mit den Editor-spezifischen Steuerelementen.
- CInternalStates
ist ein enum, das die verschiedenen Zustände repräsentiert.
- CPanelButton
ist ein enum, das den letzten Schalterzustand repräsentiert, wobei
nur zwischen QUIT und NOTQUIT unterschieden wird. Mit Hilfe dieser Flag
kann die Message-Loop verlassen werden.
Dynamische Modellierung
- Zustandsdiagramm von CList

Die dynamische Modellierung beschränkt sich auf die Darstellung
der internen Zustände des CList-Objekts. Die Message-Loop des Hauptprogramms
und die damit gegebenen Zustände fuer die Verwaltung des Optionsbereichs
werden hier nicht dargestellt. Für weitere Details sei direkt auf
den Quelltext
verwiesen.
Funktionale Modellierung
Besonderheiten der Transferfunktion
Um den Transfer zu realisieren wurden 2 Funktionen (eingabe.c,
eingabe.h)
aus dem einfachen Testprogramm verwendet, die beim Kompilieren statisch
dazugebunden werden.
Der Transfer laeuft dabei wie folgt ab, unmittelbar nach Betaetigen des
Schalters Transfer:
- Konvertierung der internen Listenrepraesentation in eine Liste des
Typs eingabe_structur.
- Aufruf der ersten Funktion (konvert_input_nach_output())zur Konvertierung
der Liste von Typ eingabe_structur in eine Liste des Typs ausgabe_structur.
- Aufruf der zweiten Funktion (schreibe_in_file()) zur Erzeugung der
Datei Streckendaten.h aus der Liste des Typs ausgabe_structur.
- Aufruf der Batch-Datei "auto", die das Projekt Steuerung
mit den vorher berechneten Streckendaten erzeugt. Ausserdem wird hier der
Debugger fuer den 80C166 aufgerufen, der mit Hilfe eines Skripts, das kompilierte
Programm an den Rechner uebertraegt. Zu diesem Zweck muss eine Verbindung
zwischen der seriellen Schnittstelle des Rechners (/dev/ttya) und dem Anschluss
J2 des Steuerrechners hergestellt werden. Die Uebertragung wird durch Aufleuchten
der Leuchtdiode LD1 signalisiert.
- Um das Fahrzeug in Bewegung zu setzen, muss die serielle Verbindung
geloest und das Fahrzeug auf einer genuegend grossen Flaeche abgestellt
werden. Durch Erzeugen eines Lichtschrankenimpulses, z.B. durch kurzes
Drehen eines Reifens, wird das interne Programm gestartet und das Fahrzeug
faehrt die ihm vorgegebene Strecke ab.
Sollten dabei irgendwelche Schwierigkeiten auftreten, so dass das Fahrzeug
den Weg nicht wie vorgegeben abfaehrt, so kann der Reset-Taster auf dem
Steuerungsrechner dazu verwendet werden die Hardware in den Grundzustand
zurueckzusetzen. Durch wiederholen des obigen Transfervorgangs kann eine
neue Uebertragung eingeleitet werden.