Steering Behaviors
Steering Behaviors
Steering Behaviors
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Fachhochschule Regensburg<br />
Fachbereich Informatik<br />
<strong>Steering</strong> <strong>Behaviors</strong><br />
Diplomarbeit<br />
zur Erlangung des akademischen Grades<br />
Diplom-Informatiker (FH)<br />
Verfasser: Thomas Feilkas Christian Schnellhammer<br />
I8IT.W I8IT.W<br />
Islinger Weg 1 Neuhauser Str. 2<br />
93055 Regensburg 94099 Ruhstorf<br />
Betreuer: Prof. Jürgen Sauer<br />
Abgabetermin: 15.01.2002
Fachhochschule Regensburg<br />
Fachbereich Informatik<br />
<strong>Steering</strong> <strong>Behaviors</strong><br />
Diplomarbeit<br />
zur Erlangung des akademischen Grades<br />
Diplom-Informatiker (FH)<br />
Verfasser: Thomas Feilkas Christian Schnellhammer<br />
I8IT.W I8IT.W<br />
Islinger Weg 1 Neuhauser Str. 2<br />
93055 Regensburg 94099 Ruhstorf<br />
Betreuer: Prof. Jürgen Sauer<br />
Abgabetermin: 15.01.2002
Fachhochschule Regensburg<br />
Fachbereich Informatik<br />
<strong>Steering</strong> <strong>Behaviors</strong><br />
Diplomarbeit<br />
zur Erlangung des akademischen Grades<br />
Diplom-Informatiker (FH)<br />
Verfasser: Thomas Feilkas Christian Schnellhammer<br />
I8IT.W I8IT.W<br />
Islinger Weg 1 Neuhauser Str. 2<br />
93055 Regensburg 94099 Ruhstorf<br />
Betreuer: Prof. Jürgen Sauer<br />
Abgabetermin: 15.01.2002
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Inhaltsverzeichnis<br />
Inhaltsverzeichnis _______________________________________________ 1<br />
1. Übersicht ____________________________________________________ 3<br />
1.1. Wie das Projekt entstanden ist __________________________________ 3<br />
1.2. Was sind <strong>Steering</strong> <strong>Behaviors</strong> ____________________________________ 4<br />
2. Theorie ___________________________________________________ 7<br />
2.1. Fahrzeugmodel _______________________________________________ 7<br />
2.2. <strong>Behaviors</strong> ____________________________________________________ 8<br />
2.2.1. Seek and Flee <strong>Behaviors</strong> __________________________________________ 8<br />
2.2.2. Arrive Behavior________________________________________________ 10<br />
2.2.3. Wander ______________________________________________________ 11<br />
2.2.4. Separation ____________________________________________________ 14<br />
2.2.5. Alignment ____________________________________________________ 16<br />
2.2.6. Cohesion _____________________________________________________ 18<br />
2.2.7. Flocking _____________________________________________________ 19<br />
2.2.8. Obstacle Avoidance ____________________________________________ 20<br />
2.2.9. Containment __________________________________________________ 26<br />
2.2.10. Containment durch Fuzzy-Logik __________________________________ 27<br />
2.2.11. SimplePathFollowing ___________________________________________ 33<br />
2.3. Mind_______________________________________________________ 34<br />
2.3.1. Einleitung ____________________________________________________ 34<br />
2.3.2. SimpleMind___________________________________________________ 35<br />
2.3.3. PriorityMind __________________________________________________ 35<br />
2.4. Simulationen ________________________________________________ 37<br />
2.4.1. Einleitung ____________________________________________________ 37<br />
2.4.2. Simulation Class _______________________________________________ 37<br />
2.4.3. Neighborhood _________________________________________________ 38<br />
2.4.4. Tile Neighborhood _____________________________________________ 42<br />
1
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
2.4.5. Path Generating________________________________________________ 45<br />
2.4.6. Regensburg Applet _____________________________________________ 55<br />
2.5. <strong>Steering</strong>Renderer ____________________________________________ 58<br />
2.5.1. Übersicht_____________________________________________________ 58<br />
2.5.2. Aufbau_______________________________________________________ 59<br />
2.6. XML zur Szenenbeschreibung _________________________________ 62<br />
2.6.1. Was ist XML? _________________________________________________ 62<br />
2.6.2. XML Definitionen______________________________________________ 63<br />
2.6.3. XML als Szenenbeschreibung_____________________________________ 64<br />
2.6.4. XML-Parser __________________________________________________ 64<br />
2.6.5. <strong>Steering</strong> XML Referenz _________________________________________ 64<br />
2.7. <strong>Steering</strong>Factory______________________________________________ 73<br />
2.7.1. Übersicht_____________________________________________________ 73<br />
2.7.2. Arbeitsweise __________________________________________________ 74<br />
2.7.3. Erweiterung der <strong>Steering</strong>Factory __________________________________ 77<br />
2.8. <strong>Steering</strong>Creator _____________________________________________ 77<br />
2.8.1. Einleitung ____________________________________________________ 77<br />
2.8.2. Bedienung des <strong>Steering</strong>Creators ___________________________________ 78<br />
2.8.3. Implementierung _______________________________________________ 92<br />
2.9. Simulation Applet____________________________________________ 94<br />
2.9.1. Einleitung ____________________________________________________ 94<br />
2.9.2. Bedienung des Simulation Applets _________________________________ 95<br />
3. Abbildungsverzeichnis ______________________________________ 98<br />
4. Literaturverzeichnis _______________________________________ 101<br />
2
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
1. Übersicht<br />
1.1. Wie das Projekt entstanden ist<br />
Im Rahmen der Vorlesung Objektorientierte Programmierung (OOP) bei Herrn<br />
Prof. Jürgen Sauer im WS 2000/2001 entstand die erste Version des Projekts<br />
“<strong>Steering</strong> <strong>Behaviors</strong>”. Ziel der Vorlesung war es, ein für die Vorlesung<br />
angemessenes Java-Applet zu entwickeln. Das Projekt “<strong>Steering</strong> <strong>Behaviors</strong>”<br />
stütze sich dabei auf die in der Siggraph 2000 veröffentlichte Arbeit von<br />
Robin Green. Diese erste Version stellte dabei ein System mit Beispielen für<br />
einfache Verhaltenskombinationen dar. Für eine benutzerdefinierte<br />
Szenenbeschreibung wurde eine selbst definierte Skriptsprache verwendet, die<br />
als Parameter an das Applet übergeben wurde.<br />
Anfang 2001 entstand dann die Idee das Projekt zu einer Diplomarbeit zu<br />
erweitern. Dabei sollten nun alle in der Arbeit von Reynold beschriebenen<br />
Verhalten implementiert werden. Die Intelligenz der Simulation wird dabei mit<br />
Hilfe einer Verhaltenssteuerung erweitert. Dadurch kann die Intelligenz an die<br />
Szenenbeschaffenheit angepaßt werden.<br />
Es enstand die Idee, anstatt der Skriptsprache für die Beschreibung der Szenen,<br />
die Metasprache XML zu verwenden. Dabei verwendet man eine moderne<br />
standardisierte und plattformunabhängige Sprache. Für die Erstellung der<br />
Szene wurde ein leistungsfähiger Editor programmiert, der jede Form von<br />
Szenen erstellen kann. Dieser erlaubt es, XML-Dateien zu lesen und zu<br />
schreiben.<br />
Eine weitere, sehr bereichernde Idee für die Arbeit, war die Implementierung<br />
eines eigenen Renderers. Dieser kann sowohl in der Simulationsdarstellung als<br />
auch im Editor verwendet werden.<br />
Das Projekt “<strong>Steering</strong> <strong>Behaviors</strong>” stellt aufgrund der Vollständigkeit und<br />
3
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
individuellen Szenenerstellung eine gute Referenz zu den Arbeiten von Craig<br />
Reynolds dar.<br />
1.2. Was sind <strong>Steering</strong> <strong>Behaviors</strong><br />
<strong>Steering</strong> <strong>Behaviors</strong> sind die logische Weiterentwicklung des Boids Modells<br />
von Craig Reynolds aus dem Jahre 1987 1 . Das als “Boids” bezeichnete<br />
Computer basierte Modell ist eine Möglichkeit zum simulieren von<br />
koordinierten Bewegungen wie sie in Fisch- oder Vogelschwärmen zu sehen<br />
ist. Der Name „Boids“ bezeichnet hierbei die einzelnen simulierten Kreaturen.<br />
Das ursprüngliche Schwarmmodell basiert auf drei einzelnen Verhalten.<br />
Hierbei dient „Separation“ zum Abwenden von Situationen in denen sich die<br />
Mitglieder des Schwarms zu dicht aufeinander befinden. „Alignment“ wird<br />
benutzt um alle Elemente des Schwarms in die selbe Richtung zu lenken. Das<br />
dritte Verhalten, „Cohesion“, dient zum steuern eines einzelnen „Boids“ zur<br />
durchschnittlichen Position seiner nächsten Nachbarn. Durch eine geschickte<br />
Kombination dieser drei einfachen Verhalten konnte Reynolds eine glaubhafte<br />
Simulation des Verhaltens von Schwärmen auf dem Rechner simulieren. Ein<br />
erstes Beispiel für eine Animation unter Verwendung dieses Modells stellt der<br />
Kurzfilm „Stanley and Stella in: Breaking the Ice“ dar. Er entstand in einer<br />
Kooperation der Symbolics Graphics Division mit Whitney / Demos<br />
Production im Jahr 1987 und wurde im Electronic Theater der SIGGRAPH<br />
1987 uraufgeführt.<br />
1 [REY87]<br />
4
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 1: Szene aus Stanley and Stella in: Breaking the Ice (1987)<br />
Die in dieser Produktion verwendeten und evaluierten Algorithmen zur<br />
Vermeidung von Hindernissen bei der Steuerung der einzelnen „Boids“<br />
präsentierte Reynolds in seiner im Jahre 1988 erschienen Arbeit unter dem<br />
Titel „Not Bumping Into Things“ 2 . Hier beschreibt er mehrere Möglichkeiten<br />
für Algorithmen und Regeln zum Ausweichen von Hindernissen. Es wird<br />
hierbei nicht auf komplexe Planungsstrategien und Pfadfindealgorithmen<br />
eingegangen, sondern rein auf Strategien basierend auf lokalen Informationen,<br />
d.h. im unmittelbaren Umkreis des Fahrzeuges.<br />
Reynolds Arbeit über <strong>Steering</strong> <strong>Behaviors</strong> 3 , die im Jahr 1999 auf der Games<br />
Developer Conference erschienen ist, erweitert die schon im „Boids“ Modell<br />
vorgestellten Verhalten. Es werden weitere Bausteine für komplexe, autonome<br />
Systeme vorgestellt. Jedes einzelne dieser Verhalten definiert nur eine<br />
bestimmte Reaktion auf die simulierte Umgebung des allgemein als Fahrzeug<br />
bezeichneten autonomen Agenten. Man erhält dadurch einen einfachen<br />
Baukasten für komplexe Systeme. Je nach dem welche Verhalten man einem<br />
Fahrzeug zuweist, desto komplexere Situationen kann dieses Fahrzeug<br />
2 [REY88]<br />
3 [REY99]<br />
5
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
meistern. Die unter dem Begriff „<strong>Steering</strong> <strong>Behaviors</strong>“ zusammengefaßten<br />
Verhalten sind dabei nur die unterste Steuerungsebene für ein autonomes<br />
System. Wie diese kombiniert werden können, wird anhand von mehreren<br />
Beispielen dargestellt.<br />
Robin Green stellte auf der SIGGRAPH 2000 eine als „<strong>Steering</strong> Behaviours“<br />
bezeichnete Arbeit vor 4 . In dieser Arbeit greift er die von Reynolds<br />
entwickelten Verhalten auf und präsentiert Beispiele für eine Implementation<br />
der einzelnen Verhalten unter Verwendung der Sprache C++. Auch werden<br />
weitere mögliche Probleme und Lösungen für diese aufgezeigt. Diese Arbeit<br />
entstand als Teil der Entwicklung des Computerspiels „Dungeon Master 2“ von<br />
Bullfrog Productions Ltd.<br />
Abbildung 2: Screenshot aus Dungeon Master 2, Bullfrog Productions Ltd.<br />
Dieses Spiel kann als gelungenes Beispiel für die Verwendung der <strong>Steering</strong><br />
4 [GRE00]<br />
6
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
<strong>Behaviors</strong> angesehen werden. Die im Spiel auftretenden autonomen Charaktere<br />
werden unter Verwendung von einzelnen einfachen Verhalten gesteuert und<br />
zeigen auf, was für einen Grad an Realismus man durch eine geschickte<br />
Kombination dieser Verhalten erreichen kann.<br />
2. Theorie<br />
2.1. Fahrzeugmodel<br />
Sowohl Craig Reynold als auch Robin Greene verwenden in ihren Arbeiten ein<br />
vereinfachtes Fahrzeugmodell. Es basiert auf der Verwendung einer Punkt -<br />
Masse zur Definition des Fahrzeuges. Ein Fahrzeug besteht aus einer Position<br />
und einer Geschwindigkeit. Zur weiteren Vereinfachung wird die Masse auf<br />
eins festgelegt und taucht deswegen bei weiteren Berechnungen nicht mehr<br />
auf. Die Ausrichtung des Fahrzeuges wird mit Hilfe der Vektoren m_localx<br />
und m_localy beschrieben. Diese beiden Vektoren bilden das lokale<br />
Koordinatensystem des Fahrzeuges und werden verwendet um zwischen<br />
Weltkoordinaten und Fahrzeugkoordinaten umzurechnen. Um die Position<br />
eines Fahrzeuges zu aktualisieren wird in jedem Frame der Animation die<br />
Geschwindigkeit mit dem erzeugten Kraftvektor addiert und das Ergebnis zur<br />
aktuellen Position addiert. Diese als Euler Integration bezeichnete Methode ist<br />
einfach zu implementieren und in diesem Fall vollkommend ausreichend um<br />
die Ergebnisse zu berechnen. Sie kann jederzeit durch stabilere<br />
Integrationsmethoden ersetzt werden, ohne etwas an der Simulation zu ändern.<br />
Das lokale Koordinatensystem wird für jedes Frame an den<br />
Geschwindigkeitsvektor angepaßt, wobei hier der Durchschnitt über die letzten<br />
drei Vektoren verwendet wird. Dies dient zum Vermeiden von möglichem<br />
„zittern“ des Fahrzeuges bei entgegengesetzt steuernden Verhalten und führt<br />
auch zu sanfteren Richtungswechseln.<br />
7
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
2.2. <strong>Behaviors</strong><br />
Anwendung<br />
2.2.1. Seek and Flee <strong>Behaviors</strong><br />
Die Seek und Flee Verhalten implementieren komplementäre<br />
Verhaltensmuster. Die verwendete Logik ist für beide gleich. Der Unterschied<br />
liegt nur im erzeugten Steuerungsvektor. Seek wird dazu verwendet, ein<br />
Fahrzeug auf ein bestimmtes Ziel hin zu steuern. Ein Beispiel hierfür wäre ein<br />
Fisch der sich direkt auf seine Nahrung zubewegt. Das Ziel kann einerseits ein<br />
fester Punkt im Raum sein, oder auch ein anderes Fahrzeug und sich in<br />
Bewegung befinden. Dagegen wird Flee benutzt, um ein einfaches<br />
Ausweichverhalten zu simulieren. Hierbei kann ebenfalls ein festes oder<br />
bewegtes Ziel vorliegen dem ausgewichen werden soll.<br />
Implementierung<br />
Die Berechnung des Steuerungsvektors ergibt sich aus den Werten für die<br />
aktuelle Geschwindigkeit des Fahrzeuges und der Position des gewünschten<br />
Ziels. Zuerst wird die Position des Ziels ausgedrückt als Vektor zwischen dem<br />
Ziel und dem Fahrzeug. Dies ist die gewünschte Geschwindigkeit. Die<br />
resultierende Kraft ergibt sich aus der Differenz zwischen diesem Vektor und<br />
dem aktuellen Geschwindigkeitsvektor.<br />
8
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Gewünschte<br />
Geschwindigkeit<br />
Aktuelle<br />
Geschwindigkeit<br />
Resultierender<br />
Steurerungsvektor<br />
(Seek Verhalten)<br />
Ziel<br />
Abbildung 3: Kraftvektor beim Seek Verhalten<br />
Beim Seek Verhalten subtrahiert man die aktuelle Geschwindigkeit des<br />
Fahrzeuges von der gewünschten Geschwindigkeit. Um den Kraftvektor des<br />
Flee Verhaltens auszurechnen, wird statt dessen der gewünschte<br />
Geschwindigkeitsvektor von der aktuellen Geschwindigkeit abgezogen. Durch<br />
diese einfache Berechnung kann das Fahrzeug entweder in Richtung des Ziels<br />
gesteuert werden, oder vom Ziel weg gesteuert werden. Zu beachten ist wie bei<br />
allen Verhalten, das der resultierende Kraftvektor die maximale Kraft des<br />
Fahrzeuges nicht überschreiten darf.<br />
Problematik<br />
Da das Seek Verhalten kontinuierlich seinen Kraftvektor erzeugt, kann sich ein<br />
in den meisten Fällen unerwünschter Effekt ergeben. Falls das Ziel statisch ist,<br />
oder sich langsamer als das Fahrzeug bewegt, führt die zum Ziel gerichtete<br />
Steuerungskraft zwar zuerst zu einem Erreichen des Ziels, steuert aber dann<br />
noch weiter über das Ziel hinaus. Nun wird wiederum ein Kraftvektor in die<br />
entgegengesetzte Richtung erzeugt und das Fahrzeug steuert wieder zurück.<br />
Die entstehende Bewegung ähnelt einer Motte, die um eine Lichtquelle fliegt.<br />
9
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Anwendung<br />
2.2.2. Arrive Behavior<br />
Das Arrive Verhalten ist eine Erweiterung des Seek Verhaltens. Es dient,<br />
ebenso wie Seek, zum Steuern des Fahrzeuges zu einem bestimmten Punkt hin.<br />
Der wichtigste Unterschied liegt in der Art des Ankommens beim Ziel. Bei<br />
Seek wird der Zielpunkt normalerweise mit maximaler Geschwindigkeit<br />
erreicht, und das Fahrzeug fährt mit der aktuellen Geschwindigkeit in die<br />
aktuelle Richtung weiter, erkennt daß es nicht mehr am Ziel ist und steuert<br />
wieder in die andere Richtung. Das Ergebnis erinnert an eine Motte, die um<br />
eine Lichtquelle kreist. Im Normalfall ist das nicht das Ergebnis das man sich<br />
erhofft hat. Das Arrive Verhalten bremst das Fahrzeug anhand von Vorgaben<br />
kontrolliert ab und stoppt es an der gewünschten Stelle.<br />
Implementierung<br />
Die eigentliche Berechnung des Steuerungsvektors geschieht zunächst genauso<br />
wie beim Seek Verhalten. Der Vektor ergibt sich aus der Differenz von der<br />
gewünschten Geschwindigkeit und der aktuellen Geschwindigkeit.<br />
Gewünschte<br />
Geschwindigkeit<br />
Aktuelle<br />
Geschwindigkeit<br />
Distanz<br />
Resultierender<br />
Steurerungsvektor<br />
Ziel<br />
Abbildung 4: Kraftvektor beim Arrive Verhalten<br />
10
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Soweit sind die beiden Verhalten in der Berechnung noch identisch. Falls das<br />
Fahrzeug sich nicht innerhalb des als m_activeDistance bezeichneten<br />
Aktivierungsbereichs befindet, wird keine Steuerungskraft erzeugt. Innerhalb<br />
des Bereichs berechnet sich die Kraft aus der Distanz zum Ziel geteilt durch<br />
die Anzahl an Schritten zum Ziel. Dadurch wird das Fahrzeug um so<br />
langsamer, je näher es zu seinem Ziel kommt. Schlußendlich bleibt es am<br />
gewünschten Punkt stehen.<br />
Problematik<br />
Es ergibt sich bei diesem Verfahren ein Problem. Durch die Verwendung von<br />
Distanz geteilt durch die Anzahl an Schritten, nähert sich das Fahrzeug dem<br />
Ziel nur asymptotisch an. Es wird im Normalfall nie vollständig exakt auf dem<br />
Zielpunkt zum Stehen kommen. Von der Sicht des Benutzers her ist hier kein<br />
Unterschied festzustellen. Probleme können sich ergeben, falls die Ausrichtung<br />
des Fahrzeuges weiterhin aktualisiert wird. Ab einem Punkt kann es zu<br />
plötzlichen Richtungsänderungen kommen, obwohl das Fahrzeug schon seit<br />
einer gewissen Zeit stillzustehen scheint. Eine mögliche Lösung ist das<br />
Verhindern des Aktualisieren des Richtungsvektors, falls die Steuerungskraft<br />
eine gewisse Stärke unterschreitet. Eine zweite Möglichkeit, die auch hier<br />
verwendet wurde, besteht im verwenden der letzten drei Richtungsvektoren<br />
beim bestimmen des aktuellen Richtungsvektors. Dadurch werden zu schnelle<br />
Änderungen und ein gewisses „Zittern“ des Fahrzeugs bei bestimmten<br />
Verhaltenskombinationen automatisch ausgeglichen.<br />
Anwendung<br />
2.2.3. Wander<br />
Fahrzeugen soll durch das Wander-Verhalten die Möglichkeit gegeben werden,<br />
sich selbstständig und ohne vordefiniertes Ziel durch die Szenerie bewegen zu<br />
11
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
können. Dies ist in etwa vergleichbar mit Ameisen, die auf dem Weg sind,<br />
Nahrung zu suchen. Die meisten Lebewesen die auf der Suche nach etwas sind,<br />
klappern die Umgebung in der Regel nicht systematisch ab, sondern bewegen<br />
sich zufällig und auf undefinierten Bahnen.<br />
Durch Kombination mit anderen Verhalten (z.B. Seek, Arrive) können die<br />
sonst geradlinigen Bahnen durch das Wander Vehalten etwas gestört werden,<br />
das sich in der Realität beispielsweise durch äußere Einflüsse, wie Wind oder<br />
Bodenunebenheiten bemerkbar macht.<br />
Fahrstrecke ohne Wander-Verhalten<br />
Fahrstrecke mit Wander-Verhalten<br />
Abbildung 5: Beispiel für eine Fahrstrecke mit dem Wander-Verhalten<br />
Implementierung<br />
Im Grunde genommen wird das Wander Verhalten durch zufällige<br />
Steuerungänderungen realisiert. Dazu gibt es mehrere Möglichkeiten. Die<br />
einfachste Möglichkeit scheint natürlich die, dem Geschwindigkeitsvektor<br />
jeder Iteration einen zufälligen Vektor zu addieren. Dadurch entsteht jedoch<br />
ein sehr unnatürliches Fahrverhalten, da sehr abrupte Richtungswechsel<br />
entstehen können. Daher wird im Folgenden ein Verfahren verwendet, das dies<br />
verhindert. Wie bei den anderen Verhalten auch, muß das Wander-Verhalten<br />
einen Steuerungsvektor zurückliefern. Jedoch gibt man dem Steuerungverktor<br />
12
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
nur eingeschränkten Freiraum, indem man nur zuläßt, daß sich deren Spitze auf<br />
einem vor dem Fahrzeug platzierten Kreis befindet. Dieser Vektor wird in<br />
Weltkoordinaten umgerechnet und als Steuerungsvektor des Wander-<br />
Verhaltens zurückgegeben.<br />
Abbildung 6: Steuerungsvektor, deren Spitze sich auf dem Kreis befindet<br />
Bei jeder Iteration addiert man zu dem aktuellen Steuerungsvektor einen<br />
Zufallsvektor, dessen Länge maximal m_rate betragen darf. Durch m_rate<br />
kann somit die maximale Steuerungsänderung festgelegt werden. Der neue<br />
Vektor wird anschließend auf den Kreis zurückprojeziert.<br />
neuer<br />
Steuerungsvektor<br />
aktueller<br />
Steuerungsvektor<br />
Abbildung 7: Berechnung des neuen Steuerungsvektors<br />
Das Verhalten lässt sich durch Variation des Kreisradius m_radius, der<br />
Kreisposition m_pos und der maximalen Richtungsänderung m_rate der<br />
gewünschten Situation anpassen. Wird der Kreis näher an dem Fahrzeug<br />
platziert, dann wird das Fahrzeug schnelle Richtungswechsel durchführen,<br />
während bei einer größeren Distanz eine viel geradlinigere Bahn beschrieben<br />
wird. Auch ein rechts- bzw. linksdrall kann durch Platzierung über oder unter<br />
13
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
der lokalen x-Achse des Fahrzeugs erreicht werden.<br />
Anwendung<br />
Abbildung 8: Verschiedene Einstellungen der Attribute<br />
2.2.4. Separation<br />
Das Separation Verhalten wird verwendet, um zu anderen Fahrzeugen einen<br />
gewissen Abstand zu halten. Dadurch werden Kollisionen unter den<br />
Fahrzeugen vermieden. Der Mensch macht das in der Realität automatisch.<br />
Bewegt er sich beispielsweise durch eine belebte Fußgängerzone, weicht er<br />
anderen Menschen instinktiv aus. Auch die anderen Menschen werden ihm<br />
ausweichen aus Angst, mit ihm zusammenzustoßen. Dabei interessieren<br />
natürlich nur die Menschen in unmittelbarer Nähe, weiter entfernte sind für den<br />
Ausweich-Instinkt unwichtig. Meist werden auch nur Menschen die sich in<br />
seiner Bewegungsbahn befinden beachtet, die hinter ihm gehenden<br />
interessieren weniger, es sei denn er will ihnen nicht zu Nahe kommen.<br />
14
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Implementierung<br />
Das Separation-Verhalten funktioniert, ähnlich wie bei elektrisch geladenen<br />
Teilchen, durch gegenseitiges Abstoßen voneinander. Zunächst müssen alle<br />
Fahrzeuge, die sich innerhalb eines bestimmten Abstands vom betreffendem<br />
Fahrzeug befinden, ermittelt werden. Dazu wird das Simulations-Object<br />
Neighborhood verwendet. Die Neighborhood-Methode<br />
getNearVehicles(v, m_nearAreaRadius)<br />
liefert einen Iterator über eine Fahrzeugliste, deren Fahrzeuge sich maximal<br />
m_nearAreaRadius vom Fahrzeug entfernt befinden. Für jedes<br />
benachbarte Objekt wird ein abstossender Vektor a r ermittelt. Dieser wird<br />
durch Differenz der Position des Fahrzeugs v und dem benachbartem<br />
Fahrzeug v2 berechnet:<br />
⎟ ⎛ xv1<br />
− xv2<br />
⎞<br />
a = ⎜<br />
⎝ yv1<br />
− yv<br />
2 ⎠<br />
r<br />
1<br />
Dieser Vektor wird durch normalisieren und skalieren auf die Länge<br />
r<br />
gebracht, wobei r die Entfernung zwischen den beiden Fahrzeugen beschreibt.<br />
near Area<br />
Abbildung 9: Berechnung des Steuerungsvektors bei Separation<br />
v 1<br />
v 2<br />
1<br />
15
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Dadurch wird die abstossende Kraft bei geringer Entfernung verstärkt, während<br />
bei grösseren Entfernungen eine leichtere Kraft entsteht. Diese Kraftvektoren<br />
werden zu einem einzigen Steuerungsvektor addiert und als Rückgabewert der<br />
r<br />
calculate()-Methode verwendet: <strong>Steering</strong>vector<br />
= ∑an<br />
Da durch die Neighborhood-Methode getNearVehicles() auch die<br />
hinteren Fahrzeuge beachtet werden, ergibt sich in einigen Anwendungen ein<br />
eher unrealistisches Fahrverhalten. Der Mensch beachtet beim Autofahren<br />
hauptsächlich die vor ihm fahrenden Fahrzeuge. Um dies zu simulieren, wird je<br />
nach Wert des Attributs lookaheadonly die Methode<br />
getNearVehiclesFront() aufgerufen, die nur die vor ihm befindlichen<br />
Fahrzeuge zurückliefert. Dadurch bremst nur das hintere Fahrzeug ab, falls es<br />
einem anderen zu nahe kommen sollte. Für einen Simulationsaufbau, der das<br />
Quequing vor einer schmalen Durchfahrt darstellt, ist es unerlässlich,<br />
lookaheadonly auf true zu setzen.<br />
Anwendung<br />
2.2.5. Alignment<br />
Fahrzeuge mit dem Alignment-Verhalten versuchen sich einer Gruppe von<br />
Fahrzeugen anzuschliessen. Die Aufgabe des Verhaltens ist das Angleichen des<br />
Richtungsvektors an die durchschnittlichen Bewegungsrichtung der<br />
umgebenden Fahrzeuge. Eine Gruppe von Fahrzeugen mit diesem Verhalten<br />
wird zuerst ihre Bewegungsrichtung aneinander anpassen und dann<br />
Richtungsänderungen als eine Einheit vollziehen. Anwendung findet dieses<br />
Verhalten beispielsweise in der Kombination mit weiteren Verhalten in<br />
Flocking-Verhalten.<br />
16
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Implementierung<br />
Um die Bewegungsrichtung des Fahrzeuges an seine Nachbarn anzugleichen,<br />
steuert das Verhalten in die durchschnittliche Fahrtrichtung der benachbarten<br />
Fahrzeuge. Dafür wird wieder ein Iterator über alle benachbarten Fahrzeuge<br />
innerhalb m_nearAreaRadius erstellt. Die Geschwindigkeitsvektoren<br />
dieser Fahrzeuge werden in einer Schleife ermittelt und summiert.<br />
Anschliessend wird durch die Anzahl der Fahrzeuge geteilt um die<br />
durchschnittliche Fahrtrichtung zu berechnen.<br />
steering<br />
near Area<br />
Abbildung 10: Berechnung des Steuerungsvektors bei Alignment<br />
Der Kraftvektor ist die Differenz zwischen dem berechneten durchschnittlichen<br />
Geschwindigkeitsvektor der Nachbarn und der eigenen<br />
Geschwindigkeitsvektors. Diese Kraft darf natürlich die maximale Kraft des<br />
Fahrzeuges nicht überschreiten. Der endgültige Steuerungsvektor wird durch<br />
Multiplikation mit dem Einflussfaktor m_influence ermittelt.<br />
17
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Anwendung<br />
2.2.6. Cohesion<br />
Das Cohesion-Verhalten ist für den Zusammenhalt einer Gruppe von<br />
Fahrzeugen zuständig. Dabei wird auf die durchschnittliche Position der<br />
benachbarten Fahrzeuge zugesteuert. Das Cohesions-Verhalten ist ein<br />
wichtiger Bestandteil des Flocking-Verhaltens. Es sollte nur in Verbindung mit<br />
dem Separation Verhalten eingesetzt werden. Ohne dieses Verhalten, steuern<br />
alle Fahrzeuge mit Cohesion auf einen gemeinsamen Punkt zu und überlappen<br />
sich.<br />
Implementierung<br />
Zunächst wird ein Iterator aller naheliegenden Fahrzeuge durch die<br />
Neighborhod-Methode getNearVehicles(…) ermittelt. Anschließend<br />
werden die Ortsvektoren der Fahrzeuge summiert und durch die Anzahl der<br />
Fahrzeuge im vorgegebenen Bereich geteilt. Auf diese dadurch ermittelte<br />
Position wird das Fahrzeug hingesteuert.<br />
near Area<br />
Abbildung 11: Berechnung des Steuerungsvektors bei Cohesion<br />
18
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Anwendung<br />
2.2.7. Flocking<br />
Flocking weist den Fahrzeugen ein Verhalten zu, das ihnen die Möglichkeit<br />
gibt, sich einer Gruppe anzuschließen. In der Natur ist das beispielsweise bei<br />
Vogelschwärmen zu beobachten. Oft sind hunderte von Vögel sehr eng<br />
nebeneinander, aber trotzdem kollidieren sie nicht. Sie passen ihre<br />
Geschwindigkeit und ihre Flugrichtung den anderen Vögel an und versuchen<br />
außerdem noch, Zusammenstösse zu vermeiden. Reynolds beschreibt dieses<br />
Verhalten aus einer Kombination der Verhalten Separation, Alignment und<br />
Cohesion.<br />
D.h. während das Separation-Verhalten Kollisionen unter den Fahrzeugen<br />
verhindert, stellt das Cohesion-Verhalten eine gewisse Anziehung<br />
untereinander sicher. Fahrzeuge die sich also einem „Schwarm“ nähern,<br />
werden von ihm eingefangen und mitgezogen. Durch das Alignment-Verhalten<br />
wird in die durchschnittliche Richtung der benachbarten Fahrzeuge gesteuert.<br />
Implementierung<br />
Der Steuerungsvektor errechnet sich aus der Summe der Kraftvektoren von<br />
Alignment, Cohesion und Separation. Dafür wird ein Vector der Länge 0<br />
erstellt, zu dem die Kraftvektoren der drei verwendeten <strong>Behaviors</strong> addiert<br />
werden. Es werden drei weitere Einflußwerte für die drei einzelnen Verhalten<br />
vorgegeben. Mit Hilfe der Attribute „Alignment“, „Cohesion“ und<br />
„Separation“ kann man die Verteilung der Kräfte innerhalb des Flocking-<br />
Verhaltens noch genauer definieren. Dadurch kann man erreichen, daß die<br />
Schwärme dichter oder lockerer sind, oder auch die Bewegungen am Rand<br />
nicht mehr so genau nachvollzogen werden.<br />
19
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Anwendung<br />
2.2.8. Obstacle Avoidance<br />
Um ein Fahrzeug in einer realistischen Weise durch eine vordefinierte<br />
Landschaft zu steuern, ist es notwendig das Fahrzeug so zu bewegen, wie es<br />
ein Betrachter erwarten würde. Dazu ist es notwendig ein Verhalten zu<br />
definieren, das es erlaubt mit Hindernissen umzugehen. Im täglichen Leben ist<br />
für Tiere und Menschen das Ausweichen von Hindernissen ein natürliches<br />
Verhalten. Wenn man das Verlangen nach einem kühlen Bier verspürt, bewegt<br />
man sich nicht auf einer geraden Linie auf den Kühlschrank zu. Unbewußt<br />
wählt man einen Weg, der einem um Hindernisse in der Welt wie Tische,<br />
Stühle und andere Dinge, die den direkten Weg versperren, herumführt ohne<br />
das man sein primäres Ziel aufgeben muß um seinen gebrochenen Zeh zu<br />
behandeln. Dieses unbewußte Ausweichen um vorgegebene Hindernisse<br />
versucht das ObstacleAvoidance Verhalten zu realisieren.<br />
Implementierung<br />
Bei der Implementierung des Obstacle Avoidance Verhalten muß zuerst<br />
definiert werden, was in der virtuellen Welt ein Hindernis darstellt. Da diese<br />
Simulation innerhalb einer zweidimensionalen Welt stattfindet, liegt es nahe,<br />
einfache geometrische Figuren als Platzhalter für komplexere Hindernisse zu<br />
verwenden. Die einfachste wählbare Form eines Hindernisses stellt der Kreis<br />
dar. Dabei ist festzulegen, daß das Hindernis vollständig innerhalb des Kreises<br />
Platz finden muß. Wobei man hier auch darauf achten sollte, nicht zuviel<br />
unnötigen Platz für die Repräsentation zu verschwenden. Für langgezogene<br />
Hindernisse wie z.B. Mauern kann ein Kreis eine äußerst schlechte<br />
Annäherung sein. Der Vorteil in der Verwendung eines Kreises liegt in den<br />
äußerst einfachen Formeln zur Berechnung von Schnittpunkten mit anderen<br />
20
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
geometrischen Körpern wie sie bei diesem Verhalten benötigt werden. Als<br />
nachteilig erweist sich die meist schlechte Annäherung an das Hindernis durch<br />
den Kreis.<br />
Abbildung 12: Beispiel für gute und schlechte Annäherung durch einen Kreis<br />
Da die Nachteile für die Verwendung von Kreisen als Platzhalter für<br />
Hindernisse die Vorteile überwiegen, wurden statt dessen Polygone verwendet.<br />
Diese bieten den Vorteil, das ein bestimmtes Hindernis aus der realen Welt,<br />
wie z.B. ein Tisch oder Stuhl, dadurch beliebig genau angenähert werden kann.<br />
Die im zweidimensionalen Raum erzielten Ergebnisse lassen sich auch ohne<br />
weiteres in den dreidimensionalen Raum übertragen.<br />
Das Obstacle Avoidance Verhalten muß im ersten Schritt herausfinden, welche<br />
Hindernisse sich in der nächsten Umgebung befinden. Dazu bedient es sich des<br />
Neighborhood Objektes, das diese Informationen bereitstellt. Diese<br />
Eingrenzung der zu überprüfenden Hindernisse ist notwendig, da sich dadurch<br />
der Zeitaufwand für die weiteren Tests schon im voraus verringern läßt. Bei<br />
großen und komplexen Szenerien mit vielen Hindernissen ist der Aufwand der<br />
Vorauswahl im Vergleich zu den eigentlichen Überschneidungstests des<br />
Verhaltens als gering anzusehen.<br />
Ermitteln des Schnittwinkels und der Entfernung<br />
Die Methode getCollisionDetails(…) liefert den Schnittwinkel und<br />
die Entfernung zum Hindernis zurück. Anhand dieser Werte wird der<br />
Gegensteuerungsvektor berechnet.<br />
21
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Dazu wird der Testvektor um die Schnittentfernung verlängert, und<br />
anschliesend senkrecht auf die Kante des Hindernisses projeziert. Diser Vektor<br />
wird nun für die Gegensteuerung verwendet.<br />
steeringvector<br />
Abbildung 13: Steuerungsvektor zum Ausweichen eines Hindernisses<br />
Optimierung durch „Exclusion-Tests“<br />
Wenn Hindernisse in der Nähe des Fahrzeuges liegen, muß das nicht unbedingt<br />
heißen, daß der Testvektor das Hindernis auch schneidet. Das ist beispielsweise<br />
dann der Fall, wenn es neben dem Fahrzeug liegt.<br />
Da ObstacleAvoidance meist von vielen Fahrzeugen verwendet wird, und die<br />
Berechnung des Steuerungsvektors relativ rechenintensiv ist, kann durch<br />
sogenannte “Exclusion-Tests” herausgefunden werden, ob der Testvektor<br />
wirklich das Hindernis schneidet. Solche Test bestehen ausschließlich aus if-<br />
Abfragen und sind dadurch recht schnell in der Abarbeitung. Sie müssen für<br />
jede einzelne Kante des Hindernisses durchgeführt werden.<br />
Test 1:<br />
Als erstes wird ein Testpunkt P generiert, der der an der Spitze des Testvektors<br />
22
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
liegt. Es können nun alle Kanten ausgeschlossen werden, deren Eckpunkte, je<br />
nach Richtung des Testvektors, beide außerhalb eines abgegrenzten Bereichs<br />
liegen (siehe Bild).<br />
Test 2:<br />
P<br />
Abbildung 14: Beispiele für Kanten, die im 1. Test verworfen werden<br />
Erst nachdem die Kante den ersten Test bestanden hat, werden die Eckpunkte<br />
in die lokalen Koordinaten des Fahrzeugs umgewandelt. Der Testvektor liegt<br />
somit auf der x-Achse.<br />
Wenn nun beide Eckpunkte über bzw. unter der x-Achse liegen, schneidet die<br />
Kante nicht den Testvektor. Solche Kanten können verworfen werden.<br />
Abbildung 15: Beispiele für Kanten, die im 2. Test verworfen werden<br />
P<br />
23
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Test 3:<br />
Der 3. Test überprüft, ob die Kante evtl. von der Rückseite getroffen wird. Das<br />
ist beispielsweise bei kleinen Hindernissen oft der Fall. Diese Kanten müssen<br />
natürlich nicht beachtet werden. Die Punkte der Polygone werden gegen den<br />
Uhrzeigersinn definiert. Dadurch kann man solche Kanten ausschließen, deren<br />
Punkt 1 unter, und Punkt 2 über der x-Achse liegt.<br />
Test 4:<br />
P2<br />
P1<br />
Abbildung 16: Beispiele für eine Rückkante, die verworfen werden kann<br />
Test 4 überprüft, ob beide Kantenpunkte größere x-Werte aufweisen, als die<br />
Testvektorlänge. Außerdem können auch Kanten verworfen werden, deren<br />
Kantenpunkte links von der y-Achse liegen. Denn in diesem Fall ist das<br />
Hindernis hinter dem Fahrzeug.<br />
24
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 17: Ausschlusskanten des 4. Tests<br />
Nach diesen 4 Tests wurden die meisten Kanten verworfen und damit ist auch<br />
Rechenzeit gespart worden. Von den verbleibenden Kanten muß nun der<br />
Winkel und die Entfernung zum Schnittpunkt berechnet werden.<br />
Als Grundlage für diese Berechnung dient die Formel: 1 1 ) ( y x x a y + − =<br />
Wobei x1 und y1 die Koordinaten des ersten Kantenpunkts beschreiben. Die<br />
Steigung a wird durch<br />
( y2<br />
− y1)<br />
a = berechnet. Setzt man dieses in die erste<br />
( x − x )<br />
2<br />
Formel ein, löst auf x auf und setzt y auf 0, erhält man die Formel:<br />
( − y ) ⋅ ( x − x )<br />
=<br />
( y − y )<br />
1 2 1<br />
x +<br />
2<br />
1<br />
x<br />
1<br />
1<br />
Das Ergebnis x ist die gewünschte Entfernung zum Schnittpunkt des<br />
Testvektors mit dem Hindernis.<br />
Der Schnittwinkel wird mit der Arcustangens-Funktion berechnet.<br />
Anmerkung:<br />
Da es auch möglich ist, daß sich Hindernisse überlagern, werden natürlich alle<br />
Kanten dieser Hindernisse zum Test herangezogen. Zum Ausweichen muß<br />
25
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
darum die Kante mit der kleinsten Schnittpunktentfernung verwendet werden.<br />
Die Gegensteuerung erfolgt damit durch das naheste Hindernis.<br />
Anwendung<br />
2.2.9. Containment<br />
Das Containment-Verhalten ist eine Erweiterung von ObstacleAvoidance. Im<br />
Gegensatz zum ObstaceAvoidance verwendet Containment insgesamt drei<br />
Testvektoren für eine Kollisionsabfrage: Einen vorne und jeweils einen links<br />
und rechts.<br />
frontdistance<br />
sidey<br />
sidex<br />
Abbildung 18: Testvektoren beim Containment Verhalten<br />
Diese Vektoren werden mit den Parametern sidex, sidey und<br />
frontdistance festgelegt (siehe Bild). Für jeden dieser drei Vektoren wird<br />
getestet, ob er ein Hindernis schneidet. Ist das der Fall, wird der Schnittwinkel<br />
und die Entfernung zum Schnittpunkt berechnet. Anhand dieser Werte wird ein<br />
Steuerungsvektor berechnet, der vom Hindernis wegsteuert.<br />
Implementierung<br />
Wie bereits erwähnt muß für jeden der Testvektoren der Schnittwinkel und die<br />
Entfernung des Schnittpunkts berechnet werden. Zu diesem Zweck wird die<br />
26
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Methode getCollisionDetails(…) verwendet. Durch Angabe des<br />
Fahrzeug, des zu testenden Hindernisses und dem Testvektor werden neben<br />
Schnittentfernung und –winkel noch die beiden Punkte der entsprechenden<br />
Schnittkante des Hindernisses zurückgeliefert. Um nicht bei jedem Hindernis<br />
diese Methode aufrufen zu müssen, wird das Neighborhood-Objekt nach<br />
Hindernissen in der Entfernung der Testvektorlänge befragt.<br />
Der Vorteil bei der Verwendung von drei Testvektoren, anstelle nur eines<br />
einzelnen, liegt in der besseren Behandlung von Situationen in denen das<br />
Fahrzeug knapp an Hindernissen entlang fahren muß. Bei ObstacleAvoidance<br />
kann es passieren, daß das Fahrzeug sich schon innerhalb des Hindernisses<br />
befindet, bevor der Testvektor eine Kollision feststellt. Die zwei zur Seite<br />
gerichteten Vektoren bei Containment testen genau den Bereich der von<br />
Obstacle Avoidance vernachlässigt wird und erlaubt dadurch eine bessere<br />
Behandlung von komplexen Situationen.<br />
2.2.10. Containment durch Fuzzy-Logik<br />
Im Gegensatz zum einfachen Containment-Verhalten (Kapitel 2.2.8) wird in<br />
der Fuzzy-Variante der Steuerungsvektor mit Hilfe von Fuzzy-Logik<br />
berechnet. Als Eingangsgrößen wird der Auftreffwinkel und die<br />
Schnittentfernung zum Hindernis verwendet. Zum ermitteln dieser Werte kann<br />
die Methode getCollisionDetails(...) genutzt werden, die genau<br />
diese Größen berechnet.<br />
Die Fuzzy-Sets<br />
Fuzzy-Systeme kodieren Regeln in numerischer Form. Die Fuzzy-Set-Theorie<br />
geht von der Annahme aus, daß alle Dinge nur zu einem gewissen Grad<br />
zutreffen.<br />
27
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Aus diesem Grund wird die Entfernung zum Hindernis in 3 Teile aufgeteilt:<br />
kleine Entfernung (PS)<br />
mittlere Entfernung (PM)<br />
große Entfernung (PB)<br />
Die unscharfen Grenzen dieser 3 Entfernungsklassen lassen sich mit folgendem<br />
Diagramm darstellen:<br />
PS<br />
PM<br />
0% 20% 50% 80% 90%<br />
Abbildung 19: Unscharfe Grenzen der Entfernung<br />
PB<br />
Abstand<br />
Es lässt sich beispielsweise direkt ablesen, daß ein Abstand von 50% der<br />
Testvektorlänge als mittlere Entfernung empfunden wird, während bei einer<br />
Entfernung von 75% sich eine halb mittel und eine halb große Entfernung<br />
ergibt. Je näher das Hindernis gekommen ist, desto stärker soll natürlich<br />
ausgewichen werden.<br />
Aber auch der Auftreffwinkel ist ein wichtiger Faktor, wie stark das Fahrzeug<br />
ausweichen soll. Ein Autofahrer der leicht von der Spur abgekommen ist, wird<br />
nur eine leichte Fahrtrichtungskorrektur machen, während er bei einem<br />
frontalen Hindernis sofort stark auszuweichen beginnt.<br />
Der Auftreffwinkel wird in 5 Teile zerlegt:<br />
negativ mittel (NM)<br />
negativ klein (NS)<br />
28
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
senkrecht, bzw. null (ZE)<br />
positiv klein (PS)<br />
positiv mittel (PM)<br />
NM<br />
NS ZE PS<br />
PM<br />
-90° -10° 0° +10° +90°<br />
Die Regeltabelle<br />
Abbildung 20: Unscharfen Grenzen des Winkels<br />
Winkel<br />
Um entsprechend der Eingangsgrößen handeln zu können, wird eine<br />
Regeltabelle benötigt. Diese Regeltabelle legt fest, bei welcher Kombination<br />
aus Entfernungs- und Winkelgrößen welche Ausgabegröße resultiert.<br />
Für das FuzzyContainment-Verhalten wird folgende Regeltabelle festgelegt:<br />
Abstand<br />
↓<br />
NM NS ZE PS PM ← Auftreffwinkel<br />
PS ZE PS PS NS ZE<br />
PM ZE PS ZE NS ZE<br />
PB ZE PS ZE NS ZE<br />
29
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Die Defuzzifizierung<br />
Als Ergebnis der Defuzzifizierung erhält man einen Wert zwischen -90 und<br />
+90 Grad, der die Steuerungsrichtung für das Ausweichen beschreibt. Der<br />
Betrag des Steuerungsvektors ist fest vorgegeben und bleibt immer konstant.<br />
NS ZE<br />
-90° -45° 0° +45° +90°<br />
Beispiel einer Ausweichsituation<br />
Abbildung 21: Diagramm zur Defuzzifizierung<br />
PS<br />
Steuerungsrichtungl<br />
Angenommen ein Fahrzeug befindet sich in der in Abbildung 22 gezeigten<br />
Situation. Dabei wird ein Abstand von 60% und ein Auftreffwinkel von 36°<br />
gemessen.<br />
36°<br />
60%<br />
Abbildung 22: Fahrzeug in einer Ausweichsituation<br />
Diese Werte werden nun als Eingabewerte für die Fuzzysteuerung verwendet.<br />
30
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
0,67 NS<br />
0,33 NM<br />
0,76 PM<br />
0,23 PB<br />
-90°<br />
0%<br />
NM<br />
PS<br />
20%<br />
-36°<br />
NS ZE<br />
-10°<br />
0° +10°<br />
PM<br />
50%<br />
PS<br />
57%<br />
80%<br />
Abbildung 23: Beispiel einer Fuzzysteuerung<br />
-90° -45° 0° +34° +45° +90°<br />
PB<br />
PM<br />
+90°<br />
90%<br />
Winkel<br />
Abstand<br />
Die dadurch resultierenden Werte von 0.67 NS und 0.33 NM für den Winkel<br />
bzw. 0.76 PM und 0.23 PB für den Abstand werden nun laut der Regeltabelle<br />
ausgewertet und in das Defuzzifizierungsdiagramm eingetragen:<br />
NS ZE<br />
PS<br />
Abbildung 24: Defuzzifizierung<br />
Steuerungsrichtungl<br />
Nach der Ermittlung des Schwerpunkts der eingeschlossenen Fläche erhält man<br />
einen Wert von +34°, der die Steuerungsrichtung des Fahrzeugs zum<br />
Ausweichen beschreibt.<br />
31
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
36°<br />
60%<br />
34°<br />
Steuerung<br />
Abbildung 25: Der Steuerungsvektor einer Fuzzy-Ausweichsteuerung<br />
Probleme bei dieser Konfiguration der Fuzzy-Sets entstehen bei konkaven<br />
Hindernissen. Da das Verhalten nur eine rechts-/links-Steuerung vornimmt und<br />
keine rückstoßende Kraft erzeugt, bleibt das Fahrzeug ab einem bestimmten<br />
Grad von spitzwinkligen Hindernissen stecken. Das kommt daher, da das<br />
Fahrzeug einmal die Kante links davon erkennt und darum rechts steuert, und<br />
anschließend die Kante rechts erkennt und darum wieder nach links steuert<br />
(siehe Abbildung 26).<br />
Abbildung 26: Problematik bei konkaven Hindernissen<br />
Dieser Effekt lässt sich durch andere Fuzzy-Konfigurationen mehr oder<br />
32
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
weniger unterdrücken. Eine andere Möglichkeit wäre, die Testvektoren links<br />
und rechts dazu zu verwenden um einen solchen Engpass zu erkennen und<br />
dementsprechend zu handeln.<br />
Anwendung<br />
2.2.11. SimplePathFollowing<br />
Ein weiteres in der Arbeit von Reynolds beschriebenes Verhalten ist das<br />
“PathFollowing” Verhalten. Hierbei wird das Fahrzeug entlang eines<br />
vordefinierten Pfades gesteuert. Der Pfad an sich besteht hierbei aus einer<br />
Folge von Wegpunkten, die in einer vorgegebenen Reihenfolge durchlaufen<br />
werden sollen. Wie von Robin Greene beschrieben 5 , gibt es drei verschiedene<br />
Möglichkeiten, wie der nächste Wegpunkt für das Fahrzeug bestimmt werden<br />
kann. Diese drei Methoden werden als „Dog on a string“ , „Reprojection“ und<br />
„Grappling Hooks“ bezeichnet. Die einfachste Art einem Pfad zu Folgen bietet<br />
die letzte Methode.<br />
Implementierung<br />
Bei „Dog on a string“ gibt es für das Fahrzeug einen festen Zielpunkt. Dieser<br />
wird linear entlang des Pfades mit einer vorgegebenen Geschwindigkeit<br />
bewegt. Es ergibt sich hierbei das Problem, diese Geschwindigkeit richtig zu<br />
wählen. Ist sie zu gering, erhält man das vom Seek Verhalten bekannte<br />
Phänomen, daß das Fahrzeug sich um den Zielpunkt wie eine Motte um das<br />
Licht bewegt. Ist die Geschwindigkeit zu schnell, können Situationen entstehen<br />
in denen das Fahrzeug sich durch vorgegebene Hindernisse bewegt.<br />
Bei der als „Reprojection“ bezeichneten Methode wird die aktuelle<br />
Fahrtrichtung des Fahrzeugs verlängert und der nächste Schnittpunkt mit dem<br />
Pfad gesucht. Dadurch erscheint das Fahrzeug intelligenter, da es die<br />
5 [GRE00]<br />
33
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Wegpunkte nicht immer ab den ersten durchlaufen muß, sonder in bestimmten<br />
Fällen diese überspringen kann und sofort den Pfad ab seiner aktuellen Position<br />
folgen kann.<br />
Problematisch sind bei dieser Methode Schleifen innerhalb des Pfades. Es muß<br />
darauf geachtet werden, das nicht plötzlich der Pfad in die falsche Richtung<br />
verfolgt wird, oder Teile des Pfades überhaupt nicht durchlaufen werden.<br />
Die als „Grappling Hooks“ bezeichnete Methode funktioniert am besten, wenn<br />
die Verbindungslinie zwischen zwei aufeinanderfolgenden Wegpunkte kein<br />
Hindernis schneidet. Das Fahrzeug steuert dann einen Wegpunkt an, und<br />
sobald dieser erreicht wurde, wird der nächste ausgewählt und angesteuert. Das<br />
SimplePathFollowing Verhalten implementiert diese Methode. Für die<br />
Erstellung der Wegpunkte ist die TileNeighborhood Klasse verantwortlich.<br />
Dieser wird der Startpunkt und der gewünschte Zielpunkt vorgegeben. Daraus<br />
werden automatisch die Wegpunkte für das Fahrzeug generiert. Das<br />
SimplePathFollowing Verhalten ruft nun die einzelnen Wegpunkte ab und<br />
steuert das Fahrzeug so zum gewünschten Ziel.<br />
2.3. Mind<br />
2.3.1. Einleitung<br />
Die Mind Klasse implementiert den in Reynolds Arbeit als „action selection“<br />
bezeichneten Teil der <strong>Steering</strong> <strong>Behaviors</strong> Logik. Ihre Aufgabe ist es auf Grund<br />
von vorgegebenen Regeln einen endgültigen Steuervektor zu erzeugen. Es<br />
spielt hierbei die Rolle des „Gehirns“ des Fahrzeuges. Die einzelnen Verhalten<br />
wie Seek, ObstacleAvoidance oder Separation spielen hierbei die Rolle von<br />
Sensoren. Jedes einzelne Verhalten kann die Umgebung auf bestimmte Art und<br />
Weise analysieren und auf Grund seiner internen Logik eine Steuerungskraft<br />
generieren. Diese Kraft basiert aber jeweils nur auf einer einzelnen speziellen<br />
Sicht der Dinge. Die Mind Klasse erhält diese „Vorschläge“ der Verhalten und<br />
34
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
trifft die Entscheidung was für eine Reaktion erfolgen soll. Für die<br />
Implementierung dieser Entscheidungsfindung gibt es mehrere Möglichkeiten,<br />
die alle ihre Vor- und Nachteile haben.<br />
2.3.2. SimpleMind<br />
Die SimpleMind Klasse implementiert die einfachste Art wie man die<br />
Entscheidung für die kombinierte Steuerungskraft treffen kann. Jedes einzelne<br />
Verhalten erhält einen als „Einfluss“ bezeichneten Wert (im Code als<br />
m_influnce bezeichnet) zugeteilt. Je nachdem wieviel Einfluß ein<br />
bestimmtes Verhalten auf den kombinierten Kraftvektor haben soll, ist dieser<br />
Einfluß höher oder niedriger angesetzt. Der vom Verhalten generierte<br />
Kraftvektor wird mit dem Einfluss multipliziert und die Vektoren werden<br />
aufaddiert. Durch dieses System lassen sich die Prioritäten der einzelnen<br />
Verhalten auf einfache Art und Weise gegeneinander abstimmen.<br />
Behavior 1 Behavior 2 Behavior n<br />
.......<br />
+<br />
<strong>Steering</strong><br />
SimpleMind<br />
Abbildung 27: Arbeitsweise des SimpleMinds<br />
Für wichtigere Verhalten wie Separation und ObstacleAvoidance wählt man in<br />
den meisten Fällen höhere Prioritäten. Verhalten wie Wander, die nicht in allen<br />
Fällen wichtig sind, werden mit niedrigerem Einfluß belegt. Dadurch stellt man<br />
sicher, daß z.B. vor einem Hindernis zuerst an das Ausweichen gedacht wird,<br />
bevor ein anderes Verhalten eine Chance auf Einfluß auf die steuernde Kraft<br />
hat.<br />
2.3.3. PriorityMind<br />
Mit Hilfe der PriorityMind Klasse kann die Einwirkung eines oder mehrerer<br />
35
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Verhalten auf die Gesamtkraft in bestimmten Fällen unterdrückt werden.<br />
Hierzu wird wie bei der SimpleMindKlasse das als „influence“ bezeichnete<br />
Attribut der Verhalten verwendet. Dieser Wert gibt an wieviel Prozent der<br />
maximalen Kraft des Fahrzeuges erzeugt werden kann. Ein Wert von z.B. 0.8<br />
entspricht hierbei 80%. Da dieser Wert frei gewählt werden kann, sind auch<br />
Werte größer als 100% möglich. Die PriorityMind Klasse verteilt die maximal<br />
verwendbare Kraft an die einzelnen Verhalten. Dabei kann aber nicht mehr<br />
Kraft erzeugt werden, als vorhanden ist. Sobald die maximale Kraft erreicht ist,<br />
kann das Verhalten entweder nur noch den übrigen Bruchteil nutzen falls ein<br />
solcher vorhanden ist, oder es wird ignoriert.<br />
Definierte Verhalten:<br />
Cohesion<br />
Separation<br />
Seek<br />
Wander<br />
0.8<br />
0.5<br />
0.2<br />
0.1<br />
Beispiel 2: Kein Hinderniss vorhanden<br />
Separation Seek Wander<br />
100%<br />
Beispiel 1: Wander wird unterdrückt<br />
Cohesion Separation Seek Wander<br />
100%<br />
Beispiel 3: Seek und Wander werden unterdrückt<br />
Separation kann nur zum Teil beitragen<br />
Cohesion Separation Seek Wander<br />
100%<br />
Abbildung 28: Beispiele für die mögliche Kraftverteilung bei PriorityMind<br />
Von Vorteil ist das PriorityMind in Situation in denen sich mehrere Fahrzeuge<br />
innerhalb eines eng abgegrenzten Bereichs bewegen. Durch eine geschickte<br />
Wahl der Einflüsse kann hierbei sichergestellt werden, daß sich einerseits<br />
Fahrzeuge nicht überschneiden und die Hindernisse nicht ignoriert werden.<br />
36
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
2.4. Simulationen<br />
2.4.1. Einleitung<br />
Die Basis für alle Simulationen ist die Simulation-Klasse. Sie dient als<br />
Ausgangspunkt um komplexe Systeme zusammenzustellen. Erste Versionen<br />
der <strong>Steering</strong> <strong>Behaviors</strong> Applets hatten den Code zum Steuern der Simulation<br />
fest integriert. Dies war nicht besonders flexibel und bei Erweiterungen mußte<br />
auf Kompatibilität mit vorherigen Versionen Rücksicht genommen werden.<br />
Durch das Verlagern der allgemeinen Funktionalität in eine eigene<br />
Klassenhierarchie kann man nun jederzeit Veränderungen an der Simulation<br />
vornehmen, ohne das man dadurch vorherige Algorithmen überschreiben oder<br />
verändern muß.<br />
2.4.2. Simulation Class<br />
Die Basisklasse für die Hierarchie der Simulationen ist die Simulation-Klasse.<br />
Sie enthält die allgemeine Schnittstelle für alle davon abgeleiteten Klassen. Um<br />
Simulationen noch flexibler zu gestalten, besitzt die Basisklasse zwei Arrays<br />
mit sogenannten Pre- und Post-Simulationen.<br />
Simulation<br />
Pre - Simulation<br />
Simulation<br />
Post - Simulation<br />
Abbildung 29: Aufteilung der Simulation Klasse<br />
Eine Pre-Simulation wird vor dem eigentlichen durchführen der Simulation<br />
aufgerufen. Dies kann für alle Arten von Simulationen verwendet werden, die<br />
37
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
ihre Daten zuerst initialisieren müssen, bevor <strong>Behaviors</strong> darauf zugreifen<br />
können. Ein Beispiel hierfür ist die Neighborhood Klasse, die ihre<br />
Distanzmatrix erst für jeden Simulationsschritt neu initialisieren muß, bevor sie<br />
verwendet werden kann.<br />
Eine Post-Simulation dient zum Nachbereiten des eigentlichen<br />
Simulationsschrittes. Ein Beispiel hierfür ist die VehicleInfo Klasse. Sie zeigt<br />
die Einflüsse der einzelnen <strong>Behaviors</strong> auf das Gesamtverhalten an und benötigt<br />
deswegen die Informationen nach dem ausführen des eigentlichen<br />
Simulationsschrittes. Eine weitere mögliche Post - Simulation wäre z.B. eine<br />
Klasse zum Überprüfen des letzten Simulationsschrittes auf Fahrzeuge in<br />
unmöglichen Positionen, wie innerhalb von Hindernissen oder sich<br />
überschneidende Fahrzeuge, und anschließende Korrektur dieser Fehler.<br />
Im eigentliche Simulationsschritt wird für jedes Fahrzeug in der Szene die<br />
zugehörige Mind Klasse aufgerufen. Diese führt dann die eigentliche<br />
Berechnung der Kräfte der einzelnen Verhalten aus und kombiniert diese<br />
anhand der jeweiligen implementierten Vorschrift.<br />
Übersicht<br />
2.4.3. Neighborhood<br />
Die Neighborhood Klasse ist eine der wichtigsten Klassen innerhalb der<br />
Simulation. Sie ist für die korrekte Funktionweise von Verhalten wie<br />
Alignment, Cohesion und aller Verhalten zum Ausweichen von Hindernissen<br />
von größter Bedeutung. Ihre Hauptaufgabe besteht im Ermöglichen von<br />
räumlichen Abfragen innerhalb der Simulationsumgebung. Man kann sowohl<br />
alle Fahrzeuge innerhalb eines vorgegebenen Radius um ein bestimmtes<br />
Fahrzeug abfragen, als auch die Hindernisse innerhalb eines festgelegten<br />
Bereichs.<br />
38
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Arbeitsweise<br />
Die Neighborhood Klasse verwendet zwei unterschiedliche Methoden für<br />
Fahrzeuge und Hindernisse, um räumliche Abfragen zu ermöglichen. Beide<br />
Methoden haben ihre Vor- und Nachteile, erfüllen aber beide die Vorgabe daß<br />
die Ergebnisse so schnell wie möglich vorliegen sollen.<br />
Die Abfrage für Fahrzeuge basiert auf einer Distanzmatrix. In dieser Matrix<br />
wird für jedes Fahrzeug die Distanz zu allen anderen Fahrzeugen hinterlegt.<br />
Eine Abfrage besteht dann nur noch in der Auswahl der Zeile des jeweiligen<br />
Fahrzeuges und dem Vergleich der einzelnen Distanzen mit dem vorgegebenen<br />
Grenzwert. Bei diesem System ist der Mittelpunkt des Objekts entscheidend<br />
bei der Auswahl. Um den Aufbau der Distanzmatrix zu beschleunigen, gibt es<br />
mehrere Möglichkeiten zur Optimierung.<br />
d5<br />
d1<br />
d4<br />
d2<br />
d3<br />
Abbildung 30: Distanzbestimmung für Neighborhood<br />
Die Bestimmung der Distanz zwischen zwei Fahrzeugen innerhalb eines<br />
zweidimensionalen Raumes geschieht anhand der Formel<br />
d +<br />
2 2<br />
= x y .<br />
Hierbei ist die Wurzel der langsamste Teil der Berechnung. Um diesen Teil der<br />
Berechnung zu umgehen, verwendet man für die Abfragen grundsätzlich die<br />
quadratische Distanz zwischen den Fahrzeugen. Hierbei ist die Distanz<br />
( ) 2<br />
2 2<br />
x y<br />
2 2 2<br />
d x + y = +<br />
= . Durch diese einfache Änderung an der Formel<br />
ergibt sich keinerlei Unterschied zu den Ergebnissen bei Verwendung der<br />
39
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
ersten Formel. Der sich daraus ergebende Vorteil liegt darin, das<br />
Wurzelfunktion nicht jedesmal berechnet werden muß. Da diese Funktion im<br />
allgemeinen trotz Unterstützung durch den mathematischen Coprozessor sehr<br />
langsam ist, ergibt sich ein nicht zu unterschätzender Zeitgewinn. Natürlich<br />
muß man auch den bei den Abfragen verwendeten Grenzwert quadrieren, um<br />
die Vergleiche innerhalb des gleichen Koordinatensystems vorzunehmen.<br />
Fahrzeug 1 X<br />
Fahrzeug 2<br />
…<br />
Fahrzeug x<br />
Fahrzeug 1<br />
Fahrzeug 2<br />
d1-2<br />
…<br />
d1-2<br />
X<br />
…<br />
d1-x d2-x<br />
…<br />
Fahrzeug x<br />
…<br />
…<br />
X<br />
…<br />
d1-x<br />
d2-x<br />
Abbildung 31: Symmetrischer Aufbau der Distanzmatrix<br />
Eine weitere Optimierungsmöglichkeit liegt im Ausnutzen der<br />
Symmetrieeigenschaft innerhalb der Matrix. Da die Fahrzeuge in den Zeilen<br />
der Matrix, den Fahrzeugen in den Spalten entsprechen, ist z.B. die Distanz<br />
zwischen Fahrzeug A und Fahrzeug B einmal in der Spalte A und Zeile B<br />
vorhanden, und ebenso in der Spalte B und Zeile A. Deswegen kann man beim<br />
Erstellen der Distanzinformationen die Anzahl der Berechnungen durch das<br />
Ausnutzen dieser Eigenschaft um die Hälfte reduzieren. Es wird nur die rechte<br />
obere Hälfte der Matrix berechnet, der Rest der Eintragungen ergibt sich<br />
dadurch automatisch.<br />
Der Nachteil an der Distanzmatrix liegt in ihrer Größe. Diese ist abhängig von<br />
der Anzahl der Fahrzeuge innerhalb der Simulation. Die Matrix besteht aus<br />
2<br />
n = Vehicles<br />
2<br />
Vehicles<br />
Elementen. Innerhalb jeder Simulationsschleife müssen jedesmal<br />
n =<br />
2<br />
Distanzen berechnet werden. Dadurch wird die Berechnung<br />
40<br />
…<br />
X
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
langsamer, je mehr Fahrzeuge sich innerhalb einer Simulation befinden.<br />
Testbereich<br />
Abbildung 32: Abfrage bei Hindernissen<br />
Die Abfrage für Hindernisse benutzt ein anderes System, um die Objekte<br />
innerhalb einer vorgegebenen Distanz zu bestimmen. Diese Distanz beschreibt<br />
dabei nicht einen Kreis um das Fahrzeug, sondern wird als die halbe Breite<br />
bzw. Höhe eines Rechtecks mit dem Fahrzeug als Mittelpunkt betrachtet. Jedes<br />
Objekt besitzt ein umschließendes Rechteck, daß das gesamte Hindernis<br />
beinhaltet. Ein Hindernis wird als innerhalb der Distanz betrachtet, wenn sein<br />
umschließendes Rechteck, das Rechteck um das Fahrzeug schneidet, oder<br />
dieses sogar komplett beinhaltet. Da es sich um Rechtecke handelt, kann man<br />
rein durch vergleichen der x und y Werte die relevanten Hindernisse<br />
bestimmen. Ein Hindernis kann verworfen werden, falls die y Werte des<br />
Rechtecks um das Hindernis kleiner als das Minimum oder größer als das<br />
Maximum der y Werte des Rechtecks um das Fahrzeug sind. Das selbe gilt<br />
auch für die x Werte. In allen anderen Fällen schneiden sich die beiden<br />
Rechtecke, oder eines der beiden überdeckt das andere.<br />
Ein Nachteil dieser Methode ist, das alle Hindernisse einer Szenerie im<br />
einzelnen überprüft werden müssen. Auch ist sie nicht sehr genau, da das<br />
umschließende Rechteck ja nur eine grobe Annäherung an das eigentliche<br />
41
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Aussehen ist. Trotz dieser Nachteile ist die Methode schnell und einfach<br />
einsetzbar.<br />
Übersicht<br />
2.4.4. Tile Neighborhood<br />
Die TileNeighborhood Klasse ist eine Erweiterung der Neighborhood Klasse.<br />
Sie dient zum Ermöglichen von räumlichen Abfragen, verwendet aber eine<br />
andere Art der internen Verwaltung als die Neighborhood Klasse. Anstelle der<br />
Distanzmatrix und der auf Clipping basierenden Abfrage für Hindernisse, wird<br />
für beide Objekttypen die gleiche Methode und eine gemeinsame Datenstruktur<br />
verwendet. Die TileNeighborhood Klasse teilt die Simulation in fest<br />
vorgegebene Abschnitte ein, die sogenannten „Tiles“. Es entsteht eine Art<br />
Schachbrettmuster. Jede einzelne dieser Flächen enthält Informationen über die<br />
Fahrzeuge und Hindernisse die diese Fläche schneiden, bzw. sich innerhalb der<br />
Fläche aufhalten. Diese Informationen werden mit Hilfe der TileInformation<br />
Klasse gespeichert. Sie enthält die Information, ob ein oder mehrere<br />
Hindernisse dieses Tile belegen, welche Hindernisse dies sind, und welche<br />
Fahrzeuge sich im Bereich des Tiles befinden. Für jede Iteration der Simulation<br />
werden die Informationen über Fahrzeuge innerhalb der Tiles aktualisiert. Das<br />
Fahrzeug wird vom vorherigem Tile entfernt, und dem neuen Tile zugeordnet.<br />
Dies erfordert nur zwei einfache Funktionen zum Umrechnen der<br />
Fahrzeugkoordinaten in TileNeighborhhod – Koordinaten, und das Entfernen,<br />
bzw. Hinzufügen eines Elements in eine Liste.<br />
Erzeugen der Datenstruktur<br />
Um diese Datenstruktur der Tiles aus den Informationen über die Szene zu<br />
generieren, muß man die Fahrzeuge und Hindernisse vom Koordinatensystem<br />
der Szenerie in das der TileNeighborhood Klasse umrechnen. Die einzelnen<br />
Tiles besitzen eine fest vorgegebene Breite und Höhe, auch die Anzahl in jede<br />
42
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Richtung ist vorgegeben. Die Umwandlung erfolgt anhand dieser Formel:<br />
⎛ x y ⎞<br />
' . Bei Fahrzeugen wird nur die eigentliche<br />
( x , y')<br />
= ⎜ , ⎟<br />
⎝ tileSizeX tileSizeY ⎠<br />
Position umgerechnet, um das zugehörige Tile zu bestimmen.<br />
Da die Hindernisse grundsätzlich als Polygon definiert sind, kann für diese<br />
Umrechnung ein Standardverfahren aus der graphischen Datenverarbeitung<br />
verwendet werden. Das Schachbrettmuster des TileNeighborhood wird als<br />
Rasterbildschirm interpretiert. Zuerst werden die Punkte des Polygons in das<br />
TileNeighborhood Koordinatensystem umgerechnet. Als nächstes wird die<br />
Kantentabelle aufgebaut. In dieser Tabelle wird für jede einzelne Kante des<br />
Polygons die Informationen gespeichert, die zum Umrechnen benötigt werden.<br />
Die dafür verwendete EdgeInfo Klasse enthält die maximale y Position der<br />
Kante, um festzulegen wann die Kante komplett gezeichnet wurde. Es wird die<br />
x Position an der minimalen y Koordinate gespeichert, um den Startpunkt<br />
festzulegen. Um die Berechnungen so schnell wie möglich durchzuführen,<br />
werden nur Integer - Werte verwendet. Da aber die Steigung einer Kante eine<br />
Fliesskommazahl ist, wird Anstelle des Ergebnisses der Berechnung, der<br />
Zähler und der Nenner als einzelne Werte gespeichert. Diese Werte werden im<br />
weiteren dazu verwendet, um zu bestimmen an welcher x Koordinate die<br />
nächste Spalte beginnt. Der Algorithmus beginnt in der untersten Spalte und<br />
liest die zugehörige EdgeInfo aus und zeichnet alle vom Polygon überdeckten<br />
Linien. Für jede weitere Spalte werden schon ausgelesen EdgeInfo Objekte für<br />
die neue Zeile angepaßt und eventuell neue Kanteninformationen ausgelesen.<br />
Dies wird bis zur letzten Spalte des Polygons wiederholt.<br />
Bei der Verwendung dieses Algorithmus zum Generieren der<br />
Tileinformationen tritt ein Problem auf. Es ergeben sich bei der Umwandlung<br />
gewisse Ungenauigkeiten. Die erste Ungenauigkeit ergibt sich bei der<br />
Umwandlung der Eckpunkte des Hindernispolygons von Weltkoordinaten die<br />
in Double Werten definiert sind in Tilekoordinaten die als Integer gespeichert<br />
43
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
sind und einen Bereich von mehreren Pixel überdecken. Bei der Anpassung der<br />
Start und Endwerte für das Zeichnen einer Spalte ist nicht garantiert, das die<br />
jeweils äußersten vom Algorithmus belegten Tiles auch das Hindernis komplett<br />
überdecken. In den meisten Fällen wird zwar der innere Teil des Hindernisses<br />
belegt, aber ein Großteil der Kanten bleibt unbelegt. Da aber diese unbelegten<br />
Tiles dazu führen, das Verhalten wie Cohesion und Obstacle Avoidance mit<br />
falschen Informationen arbeiten, wurde auf diesen Algorithmus bei der<br />
endgültigen Implementierung der TileNeighborhood Klasse verzichtet.<br />
Um die Probleme des Rasterization Algorithmus zu umgehen, wurde auf eine<br />
einfachere, aber dafür weitaus rechenintensivere Methode zurückgegriffen. Da<br />
die Umwandlung von Hindernissen in Tile spezifischen Informationen nur<br />
einmal am Start der Simulation abgearbeitet werden muß, stellt die<br />
Verwendung eines rechenintensiveren Algorithmus kein großes<br />
Performanceproblem dar. Zuerst wird das in Weltkoordinaten definierte<br />
Polygon mit Hilfe eines Standard Java-Polygonobjekts dargestellt. Die dabei<br />
stattfindende Umwandlung der Koordinaten von double auf integer Werte stellt<br />
dabei eine zu Vernachlässigende Ungenauigkeit dar. Zunächst wird der zu<br />
betrachtende Ausschnitt innerhalb der Tiles festgelegt. Dazu bestimmt man die<br />
maximale und minimale x und y Position innerhalb des Hindernisses. Diese<br />
legen ein Rechteck fest, in dem sich das gesamte Objekt befindet. Innerhalb<br />
dieses Rechtecks werden zunächst die Eckpunkte jedes Tiles auf<br />
Überschneidung mit dem Polygon getestet. Dadurch kann schon hier in den<br />
meisten Fällen die Entscheidung getroffen werden, ob das Tile vom Hindernis<br />
belegt wird. Falls dieser Test zu keiner Überschneidung führt, wird jeder<br />
zweite Pixel innerhalb des Tiles auf Überschneidung getestet. Nur falls auch<br />
dieser Test ein negatives Ergebnis liefert, kann man sicher sein, das jedes Tile<br />
korrekt belegt wurde.<br />
44
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Bestimmen von Objekten im vorgegebenen Radius<br />
Die Hauptaufgabe der Neighborhood Klassen ist die Bestimmung von<br />
Objekten innerhalb eines bestimmten Radius mit einem Fahrzeug als<br />
Mittelpunkt. In der TileNeighborhood Klasse legt der übergebene Radius die<br />
Anzahl an Tiles fest, die zu Überprüfen sind. Im Gegensatz zur Neighborhood<br />
Klasse, wird hier ein Rechteckiger Bereich um das Fahrzeug getestet, anstelle<br />
eines Kreisförmigen Bereichs. Dadurch kann es bei manchen Verhalten bei<br />
Verwendung der TileNeighborhood Klasse zu leicht abgeänderten Ergebnissen<br />
kommen. Von jedem Tile innerhalb des festgelegten Bereichs wird je nach<br />
Abfrage das Array mit den Fahrzeugen, bzw. Hindernissen, ausgelesen und in<br />
das Ergebnisarray kopiert. Es muß nur bei der Abfrage nach Fahrzeugen darauf<br />
geachtet werden, daß das zentrale Fahrzeug nicht in das Ergebnis übernommen<br />
wird. In der Definition der Abfragefunktionen in der Neighborhood Klasse<br />
wird das zentrale Fahrzeug nicht zurückgeliefert, deshalb muß auch die<br />
TileNeighborhood Klasse diese Spezifikation erfüllen.<br />
Übersicht<br />
2.4.5. Path Generating<br />
Die von Reynolds entwickelten Verhalten dienen alle zum Steuern eines<br />
Fahrzeuges. Hierbei wird im allgemeinen nur die nähere Umgebung des<br />
Fahrzeuges analysiert und auf Basis dieser Daten die Steuerungskraft<br />
berechnet. Um nun ein Fahrzeug durch eine einfach aufgebaute Simulation zu<br />
steuern reicht diese Art der Umgebungsanalyse aus um ansprechende<br />
Ergebnisse zu erzielen. Sobald die Umgebung eine gewisse Komplexität und<br />
einen gewissen Umfang erreicht, muß man seinen Weg durch die Simulation<br />
vorausplanen um gute Ergebnisse zu erzielen. Wenn zum Beispiel das Ziel<br />
durch Hindernisse verdeckt wird, kann es zu Situationen kommen, in denen<br />
eine Kombination von „Seek“ und „ObstacleAvoidance“ einfach keine<br />
45
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Möglichkeit hat, das gewünschte Ziel zu erreichen.<br />
Für diese Art von Problemen gibt es das „PathFollowing“ verhalten, das sich<br />
auf vordefinierte Pfade durch komplexe Situationen stützt. Um diese Pfade<br />
interaktive zu erzeugen, gibt es mehrere Algorithmen. Alle diese Algorithmen<br />
erwarten eine Darstellung der Welt als gewichteter, oder ungewichteter Graph.<br />
Da die Simulation aber aus einer Kombination von Fahrzeugen und<br />
Hindernissen innerhalb eines kontinuierlichen Raumes besteht, muß man eine<br />
andere Repräsentation der Daten verwenden. Wenn man Fahrzeuge außer acht<br />
läßt, besteht die Simulation aus Hindernissen, die wiederum aus Polygone<br />
bestehen. In der Arbeit von Byan Stout 6 sind unterschiedliche Möglichkeiten<br />
der Repräsentationen beschrieben.<br />
Abbildung 33: Beispiel für eine Umwandlung in eine auf Tiles basierende Darstellung<br />
Die einfachste Methode, die auch als TileNeighborhood Klasse implementiert<br />
wurde, verwendet eine Aufteilung der Welt in Rechtecke mit vorgegebener<br />
Höhe und Breite. Falls ein Hindernis ein Rechteck überschneidet oder<br />
überdeckt, wird es als unzugänglich markiert. Je nach dem wie klein die<br />
Ausmaße der Rechtecke gewählt wurden, desto genauer wird die Darstellung<br />
aber der Speicherverbrauch steigt auch dementsprechend an. Der Vorteil dieser<br />
Methode liegt in der einfachen Umsetzung und der fast Stufenlosen Variierung<br />
der Genauigkeit. Ein Nachteil ist die Ungenauigkeit der Aufteilung bei einer<br />
Wahl von großen Rechtecken. Man muß bei der Wahl der Parameter abwägen,<br />
6 [STO96]<br />
46
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
wie genau die Darstellung sein soll und wieviel Speicher man dafür zur<br />
Verfügung hat.<br />
Eine Erweiterung davon sind sogenannte „Quadtrees“. Die Welt wird hierbei in<br />
vier Rechtecke eingeteilt. Jedes Rechteck, wird rekursiv in 4 weitere Rechtecke<br />
aufgeteilt, falls sein Inhalt nicht einen gewissen Anteil an Hindernissen<br />
aufweist. Durch diese Aufteilung erhält man einen Graphen, der sich sehr nah<br />
an die ursprüngliche, kontinuierliche Welt hält, wobei hier der<br />
Speicherverbrauch etwas niedriger anzusetzen ist, als es bei der einfachen Tile<br />
Methode der Falls ist.<br />
Erstellen von Pfaden<br />
Der am weitesten verbreitete Algorithmus zum schnellen Auffinden von<br />
Pfaden innerhalb eines Graphen ist der als „A*“ bezeichnete Algorithmus. Er<br />
ist eine Erweiterung der Breitensuche und berücksichtigt auch Gewichtungen<br />
bei der Erstellung der Pfade. Grundlage sind zwei Datenstrukturen, die Open-<br />
List in der die als Nächstes zu betrachtenden Knoten abgelegt werden und die<br />
Closed-List, in der die bereits bewerteten Knoten gespeichert werden. Im Falle<br />
von A* ist die Open-List im allgemeinen als Prioritätswarteschlange<br />
implementiert. Knoten mit niedrigeren Bewertungen, d.h. mit am wenigsten<br />
Kosten verursachenden Pfaden, werden bei der weiteren Suche favorisiert.<br />
Dadurch werden zunächst die momentan am besten Erscheinenden Pfade<br />
weiter verfolgt. Im Falle einer homogenen Simulationslandschaft wird durch<br />
dieses Bewertungs- und Auswahlschema sofort ein direkter Pfad zum Ziel<br />
erzeugt, ohne das zu viele Knoten überprüft werden müssen. Für die Closed-<br />
List eignen sich mehrere Datenstrukturen, diese Implementierung verwendet<br />
ein einfaches Array. Die Bewertung der Knoten geschieht anhand einer<br />
sogenannten „Distanzfunktion“. Diese Funktion liefert eine Schätzung zurück,<br />
wie hoch die Kosten für einen direkten Pfad von diesem Knoten bis zum Ziel<br />
sein werden. Hierfür gibt es vier mögliche Implementierungen. Der<br />
47
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Unterschied liegt jeweils in der Bestimmung der Distanz zwischen dem Knoten<br />
und dem Ziel. Bei allen wird die berechnete Distanz mit den geschätzten<br />
Kosten für einen Schritt multipliziert. Die Wahl der geschätzten Kosten<br />
beeinflußt in nicht zu unterschätzender Weise die Qualität der Suche. Bei einer<br />
falschen Schätzung erhöht sich der Aufwand zum auffinden des Pfades in nicht<br />
unbeträchtlicher Weise. Die einfachste Funktion zum bestimmen der Distanz<br />
zwischen zwei Knoten, ( ∆ x, ∆y)<br />
max , bestimmt die Abweichung in x und y<br />
Richtung, und wählt dann den maximalen Wert der beiden um die Schätzung<br />
zu berechnen. Die als „euclidean“ bezeichnete Funktion bestimmt die Distanz<br />
zum Ziel mit<br />
d +<br />
2 2<br />
= x y , der Standardformel zur Bestimmung der Distanz<br />
zwischen zwei Punkten. Bei der „Diagonal“ Funktion werden zuerst alle<br />
diagonalen Knoten gezählt, bis man in der Zeile, bzw. Spalte des Ziels ist.<br />
Dann werden noch die übrigen Knoten auf direktem Wege hinzugezählt. Die<br />
vierte Funktion, als „Manhattan“ bezeichnet, benutzt d = abs(<br />
∆x)<br />
+ abs(<br />
∆y)<br />
als Distanz zwischen Knoten und Ziel.<br />
Die Bewertung eines Knotens geschieht durch die Formel f ( n)<br />
g(<br />
n)<br />
+ h(<br />
n)<br />
( )<br />
= .<br />
Wobei hier f n die Bewertung des Knotens darstellt. Je kleiner dieser Wert,<br />
desto wahrscheinlicher wird der Pfad über diesen Knoten im nächsten Schritt<br />
weiterverfolgt. g(n) stellt die momentan geringsten Kosten dar, die benötigt<br />
werden um zu diesem Knoten zu gelangen. Es sind die Kosten für den bisher<br />
am niedrigsten bewerteten Pfad vom Start zu diesem Knoten. Dieser Wert kann<br />
sich im Verlauf der Berechnungen noch ändern, falls ein besserer Pfad zu<br />
diesen Knoten gefunden wird. h(n) enthält die geschätzten Kosten um das Ziel<br />
von diesem Knoten aus zu erreichen. Für die Berechnung dieses Wertes wird<br />
eine der vier vorher beschriebenen Funktionen verwendet. Durch die<br />
Bewertung der Knoten und der Schätzung der erwarteten Kosten, arbeitet der<br />
A* Algorithmus wesentlich zielgerichteter als eine einfache Breiten- oder<br />
Tiefensuche. Es werden im allgemeinen Fall wesentlich weniger Knoten<br />
48
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
untersucht und dadurch ein nicht zu unterschätzender Teil an Rechenleistung<br />
eingespart. Ein weiterer Vorteil ergibt sich aus der Bewertung der Knoten. Da<br />
die Kosten für das Überqueren eines Knotens bei den Berechnungen<br />
berücksichtigt werden, werden Knoten mit hohen Kosten automatisch an das<br />
Ende der Prioritätswarteschlange angefügt. Dadurch werden zuerst Pfade durch<br />
„leichter“ zu bewältigendes Terrain gesucht. Trotz all dieser Vorzüge hängt die<br />
Rechenzeit nicht unwesentlich von der Größe des zu durchsuchenden Bereichs<br />
und der Verteilung der Hindernisse ab. Es ist ohne Probleme möglich,<br />
Situationen aufzubauen, in denen trotz aller Optimierungen jeder einzelne<br />
Knoten betrachtet werden muß, um ein Ergebnis zu liefern. Auch ist der<br />
erzeugte Pfad nicht immer der optimale Pfad. Dies stellt eher die Ausnahme<br />
dar, da beim ersten gefundenen Pfad die Suche abgebrochen wird. Der<br />
Algorithmus garantiert zwar einen Pfad solange es eine Lösung gibt, aber er<br />
garantiert nicht, daß es der absolut optimale Pfad vom Start zum Ziel ist. Um<br />
dies garantieren zu können, müßten alle möglichen Pfade erstellt und bewertet<br />
werden, was äußerst Aufwendig wäre und auch ein hohes Ausmaß an<br />
Rechenleistung erfordern würde.<br />
Als Referenz ist der Algorithmus hier noch als Pseudocode aufgeführt, wie er<br />
auch in der Arbeit von Bryan Stout beschrieben wird 7 :<br />
7 [STO96]<br />
49
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
priorityQueue Open<br />
list Closed<br />
AStarSearch<br />
s.g = 0<br />
s.h = CalcHeuristic(s) // The estimate from start<br />
to finish<br />
s.f = s.g + s.h // The evaluation of the<br />
node<br />
s.parent = null // The first node<br />
terminates the path<br />
push s on Open<br />
while Open is not empty<br />
pop Node n from Open<br />
if n is goal node<br />
construct path<br />
return success<br />
end if<br />
for each successor n' of n<br />
newg = n.g + cost(n', n)<br />
if n' is in Open or Closed and n'.g
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Das Beispielapplet zum Generieren von Pfaden<br />
Abbildung 34: Screenshot des AlgorithmTest Applets<br />
Um die Arbeitsweise des A* - Algorithmus besser zu verdeutlichen, wurde ein<br />
Beispielapplet erstellt. Innerhalb des Applet kann man beliebige Situationen<br />
aufbauen und diese dann durch den Pfadfindealgorithmus lösen lassen.<br />
Im linken unteren Bereich des Applets befindet sich die Darstellung des Szene.<br />
Hier kann man mit Hilfe der Maus den Start- und Endpunkt festlegen, und<br />
weitere Objekte wie undurchdringliche., oder schwer zugängliche Bereiche<br />
erstellen.<br />
51
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 35: Die Karteneinstellungen des Applets<br />
Im Bereich „Map“ wählt man aus, welches Element auf der Karte plaziert wird,<br />
wenn die linke Maustaste gedrückt wird. Die ersten vier Wahlmöglichkeiten,<br />
„Empty“ bis „Impossible“, stellen die jeweiligen Kosten für ein einen Knoten<br />
dar. Hierbei wird „Empty“ als weißes Kästchen gezeichnet, „Impossible“ als<br />
schwarzes Kästchen. „Medium“ und „Hard“ werden dementsprechend als<br />
hellgraues, bzw. dunkelgraues Kästchen gezeichnet. Knoten die mit<br />
„Impossible“ als Kosten deklariert sind, werden vom Suchalgorithmus nicht in<br />
Betracht gezogen. Sie stellen damit Hindernisse oder Mauern dar. Durch die<br />
Auswahl von „Start“ oder „Finish“ kann man den Start- und den Endpunkt auf<br />
der Karte festlegen. Hierbei wird der Startpunkt als grüner Kreis gezeichnet<br />
und der Endpunkt als roter Kreis.<br />
Abbildung 36: Der Geschwindigkeitsregler<br />
Das „Speed“ Steuerelement dient zum Einstellen der Geschwindigkeit der<br />
Simulation. Je weiter der Balken nach rechts gezogen wird, desto schneller<br />
läuft die Simulation ab. Dadurch kann der Ablauf der Suche im einzelnen<br />
dargestellt werden.<br />
Abbildung 37: Das Algorithmus - Auswahlfeld<br />
Mit Hilfe des „Algorithm“ Auswahlfeldes kann man den verwendeten<br />
Suchalgorithmus auswählen. Es ist nur der A* Algorithmus implementiert,<br />
man könnte im weiteren zu Vergleichszwecken noch andere Algorithmen, wie<br />
zum Beispiel Breitensuche, oder Dijkstra’s Suchalgorithmus implementieren.<br />
52
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 38: Das Distanzfunktion - Auswahlfeld<br />
Das „Distance Funktion“ Auswahlfeld dient zum Auswählen der verwendeten<br />
Distanzfunktion. Wie schon vorher beschrieben gibt es 4 Mögliche Funktionen,<br />
die zum Berechnen der geschätzten Kosten zum Ziel verwendet werden<br />
können. Durch Auswählen von unterschiedlichen Funktionen, kann man den<br />
Einfluß der Näherung auf den Erzeugten Pfad beobachten. Die erzeugten Pfade<br />
können dabei recht unterschiedlich ausfallen.<br />
Abbildung 39: Der Regler für die geschätzen Kosten<br />
„Heuristic Cost“ dient zum Einstellen der geschätzten mittleren Kosten um von<br />
einem Feld zum nächsten zu gelangen. Dadurch kann man die Näherung die<br />
aus den Berechnungen der Distanzfunktionen entstehen noch genauer<br />
einstellen. Die Werte hier liegen im Bereich von 2, was einem leerem Feld<br />
entspricht, bis zu 9, einem als „Hard“ definierten Feld. Veränderungen an<br />
diesem Wert, zeigen wie sehr die Effizienz des Algorithmus von gut gewählten<br />
Parametern abhängt. Falls dieser Wert zu klein gewählt wird, werden zu viele<br />
unnötige Knoten in Betracht gezogen. Die Suche ist breiter, und nicht mehr so<br />
zielgerichtet.<br />
53
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 40: Die Steuerungsknöpfe für die Simulation<br />
Mit Hilfe des „Start“ Buttons wird die Simulation gestartet. Der „Reset /<br />
Abort“ Button dient einerseits zum Abbrechen einer laufenden Simulation,<br />
andererseits werden die Ergebnisse der letzten Suche gelöscht. Der „Clear“<br />
Button dient zum löschen der gesamten Erstellten Szene. Hierbei wird nur der<br />
Start- und Endpunkt nicht verändert. Alle Knoten werden wieder in den Status<br />
„Empty“ gesetzt.<br />
54
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 41: Beispiel eines erzeugten Pfades<br />
Sobald auf „Start“ gedrückt wurde, wird ein Pfad vom Start zum Ziel<br />
berechnet. Hierbei werden die Knoten in der „Open-List“ mit blauer Farbe<br />
markiert, die Knoten in der „Closed-List“ mit grüner Farbe. Jeder betrachtete<br />
Knoten enthält eine orange Linie, die ihn mit seinem übergeordneten Knoten<br />
verbindet. Dadurch kann man die bereits erzeugten Pfade erkennen. Sobald das<br />
Ziel erreicht wurde, werden die zum endgültigen Pfad gehörenden Knoten mit<br />
einem roten Rahmen versehen.<br />
2.4.6. Regensburg Applet<br />
Um den A* Pfadfindealgorithmus in Verbindung mit dem<br />
55
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
SimplePathFollowing Verhalten zu demonstrieren, wurde das Regensburg<br />
Applet erstellt. Bestandteil dieses Programms ist ein Kartenausschnitt aus der<br />
Regensburger Innenstadt. Diese wurde aus der auf der Homepage der Stadt<br />
Regensburg (www.Regensburg.de) online verfügbaren Karte der Stadt<br />
entnommen. Das Applet zeigt nur den Teil der Innenstadt, der in dieser Karte<br />
in der höchsten Zoomstufe verfügbar ist. Dies entspricht einem<br />
Kartenausschnitt von der Größe 1568 mal 1176 Pixeln.<br />
Abbildung 42: Screenshot des Regensburg Applets<br />
Das Fahrzeug in der Simulation wird von einem SimpleMind Objekt mit<br />
SimplePathFollowing als einziges Verhalten gesteuert. Die Simulation<br />
verwendet die TileNeighborhood Klasse für die interne Darstellung der<br />
Simulationsumgebung. Da der Pfadfindealgorithmus auf einem Netzwerk<br />
basiert, wird die Information über die Straßen in Regensburg mit Hilfe von<br />
56
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
einzelnen Tiles dargestellt. Ein einzelnes Tile hat eine Höhe und Breite von 10<br />
Pixeln. Es enthält Informationen über die Zugänglichkeit des Tiles gespeichert<br />
im als m_accessible Bezeichneten Attribut. Des weiteren enthält es<br />
Informationen zur Bewertung des erzeugten Pfades wie g(n), h(n) und f(n).<br />
Die Information für die Belegung der einzelnen Tiles ist ein einer eigenen<br />
Datei hinterlegt. Diese Datei ist sehr einfach aufgebaut und enthält alle<br />
notwendigen Informationen um die Tiles korrekt zu belegen.<br />
Abbildung 43: Die Steuerelemente des Regensburg Applets<br />
Im unteren Bereich des Applets befinden sich die Steuerelemente für die<br />
Simulation. Mit Hilfe der als „Show Grid“ bezeichneten Checkbox kann man<br />
das intern verwendete Gitternetz ein- oder ausschalten. Die Dargestellten<br />
Kästchen entsprechen den in der TileSimulation verwendeten, einzelnen Tiles.<br />
Die „Show Path“ Checkbox dient zum Einschalten der Anzeige des erzeugten<br />
Pfades. Sobald der Benutzer ein neues Ziel auf der Karte vorgibt, wird ein<br />
neuer Pfad vom Fahrzeug zum Ziel erstellt. Die Wegpunkte dieses Pfades<br />
werden als einzelne rote Kästchen auf der Karte dargestellt. Die vom Fahrzeug<br />
bereits erreichten Wegpunkte werden automatisch entfernt und verschwinden<br />
von der Darstellung. Auf der rechten Seite der Steuerelemente befindet sich<br />
eine Auswahlbox mit den zur Verfügung stehenden Zoomstufen. Der Benutzer<br />
kann hierbei zwischen 50%, 100%, 150% und 200% Zoom wählen. Der untere<br />
Bereich der Steuerelemente dient einem Anzeigefeld mit Hinweisen zu den<br />
Steuerelementen die sich gerade unter der Maus befinden. Dadurch erhält der<br />
Benutzer jederzeit kontextbezogene Hilfe zu den Elementen des Applet mit<br />
denen er interagieren kann.<br />
57
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
2.5. <strong>Steering</strong>Renderer<br />
2.5.1. Übersicht<br />
Die Klasse <strong>Steering</strong>Renderer dient der Darstellung aller Objekte innerhalb<br />
einer Simulation. Die Bestandteile der Szenerie, wie zum Beispiel Fahrzeuge<br />
oder Hindernisse, zeichnen sich nicht selbst, sondern enthalten nur die<br />
notwendigen Informationen über Position, Ausrichtung und weitere<br />
Informationen zur Darstellung. Die <strong>Steering</strong>Renderer Klasse setzt diese<br />
Objektbeschreibungen in eine zweidimensionale Darstellung um. Dabei<br />
werden die von den Objekten in Weltkoordinaten angegebenen Positionen in<br />
Bildschirmkoordinaten umgerechnet, wobei Rücksicht auf den eingestellten<br />
Zoomfaktor und Größe und Position des sichtbaren Ausschnitts genommen<br />
wird.<br />
Durch diese Aufteilung in eine Beschreibung der Simulation und eine Klasse<br />
zur Darstellung auf dem Bildschirm ergeben sich mehrere Vorteile. Die auf<br />
Java – AWT basierende <strong>Steering</strong>Renderer Klasse, kann jederzeit durch eine<br />
neue und erweiterte Darstellungklasse ausgetauscht werden. So kann man die<br />
Vorteile von Java2d oder Java3d nutzen, sobald diese auch von den meisten<br />
Browsern unterstützt werden. Da zum Zeichnen ein Graphics-Objekt<br />
verwendet wird, kann die Klasse sowohl beim Applet als auch beim Editor<br />
eingesetzt werden. Dadurch muß nicht für jede Anwendung ein spezieller Code<br />
zum Zeichnen der Objekte geschrieben werden. Es lassen sich auch Dinge wie<br />
z.B. das Zoomen und Verschieben der Ansicht mit Hilfe des Renderers leichter<br />
lösen, als dies bei in den Objekten integriertem Zeichencode möglich wäre. Ein<br />
weiterer Vorteil ist die automatisch erzeugte Liste mit allen sichtbaren<br />
Objekten und ihren Positionen auf dem Bildschirm. Mit ihrer Hilfe kann man<br />
ohne großen Aufwand Benutzeraktionen wie selektieren und verschieben von<br />
Objekten realisieren. Dieser Effekt ließe sich zwar auch bei sich selbst<br />
zeichnenden Objekten realisieren, aber der Aufwand wäre bedeutend höher<br />
58
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
ausgefallen. Außerdem wäre man in diesem Fall gezwungen, den selben Code<br />
für jede Klasse von Objekten nochmals implementieren. Was umständlich und<br />
vor allem äußerst fehleranfällig ist.<br />
2.5.2. Aufbau<br />
Als Basis für die Objekte in der Szene dient die Geometrie Klasse. Sie enthält<br />
die notwendigen Informationen, um das Objekt mit Hilfe des<br />
<strong>Steering</strong>Renderers darzustellen. Die m_pos Variable enthält die Position des<br />
Objekts in Weltkoordinaten. Die Ausrichtung wird durch m_localX und<br />
m_localY beschrieben. Diese beiden Variablen beinhalten die lokale X- und<br />
Y-Achse des Objekts. Sie werden verwendet, um mit Hilfe der Funktionen<br />
localToWorld und worldToLocal zwischen Objekt relativen<br />
Koordinaten und Weltkoordinaten umzurechnen.<br />
Die Beschreibung für die Darstellung des Objekts ist im Vector m_shapes<br />
hinterlegt. Basis für alle Beschreibungen ist die RenderInfo Klasse. Ein<br />
Geometrie Objekt kann durch mehrere unterschiedliche RenderInfo Objekte<br />
beschrieben werden. Wobei hier auch unterschiedliche Typen verwendet<br />
werden können. Die Gestaltung der Objekte wird dadurch flexibler.<br />
59
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 44: Klassendiagramm für den <strong>Steering</strong>Renderer<br />
Die am meisten verwendete, auf RenderInfo basierende Klasse, ist<br />
PolygonShape. Sie enthält die notwendigen Informationen, um ein Polygon auf<br />
dem Bildschirm auszugeben. Im allgemeinen besteht ein Polygon aus<br />
mindestens drei Punkten, die in Objektkoordinaten angegeben werden müssen.<br />
Dabei ist auch zu beachten, das die Punkte zwingend in einer bestimmten<br />
Reihenfolge zu übergeben sind. Dies ist notwendig, da die Berechnung des<br />
Normalenvektors einer Seite, je nach Reihenfolge der Punkte, verschiedene<br />
Ergebnisse liefert. Durch eine fest vorgegebene Reihenfolge können solche<br />
Fehlermöglichkeiten ausgeschlossen werden. Polygone können in zwei Arten<br />
ausgegeben werden. Einerseits als gefülltes Objekt, andererseits ungefüllt und<br />
nur den Umriß verwendend.<br />
Die VectorShape Klasse dient zum Darstellen von Vektoren. Sie wird<br />
hauptsächlich innerhalb des Editors verwendet, um z.B.<br />
Geschwindigkeitsvektoren darzustellen. Gespeichert wird nur der eigentliche<br />
Vektor in der Variable m_vector unter Verwendung der Vector2d Klasse<br />
und eine zusätzliche Längeninformation in der Variable m_length. Der<br />
endgültige gezeichnete Vektor ergibt sich aus der in Weltkoordinaten<br />
60
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
umgerechneten m_vector Komponente, skaliert mit dem m_length Faktor.<br />
Um Innerhalb der Simulation Bitmaps verwenden zu können, wurde die Tile<br />
Klasse implementiert. Sie enthält in der Variablen m_texture ein<br />
benutzerdefiniertes Bitmap. Im Gegensatz zu Polygonen und Vektoren, werden<br />
Bitmaps zusammen mit dem Geometrieobjekt skaliert, aber nicht rotiert. Dies<br />
hängt mit der fehlenden Unterstützung des AWT Toolkits von rotierten<br />
Bitmaps zusammen. Eine auf Java2D basierende <strong>Steering</strong>Renderer Klasse<br />
könnte diesem Problem Abhilfe schaffen.<br />
Die Circle Klasse dient zum Zeichnen von Kreisen. Diese werden im<br />
Gegensatz zum AWT mit Mittelpunkt und Radius definiert. Dabei ist die<br />
Position des Geometrie Objekts als Mittelpunkt fest vorgegeben. Die<br />
Umrechnung in die Werte für die Zeichnungsfunktionen des AWT werden von<br />
der Renderer Klasse automatisch erledigt. Wie auch Polygone können Kreise<br />
gefüllt, oder nur als Umriß dargestellt werden.<br />
Die Umwandlung einer Szene in eine Darstellung auf dem Bildschirm<br />
geschieht in zwei Schritten:<br />
Abbildung 45: Ablauf der Koordinatentransformation<br />
Zuerst werden im Clipping Schritt alle Objekte verworfen, die den sichtbaren<br />
Bereich nicht schneiden. Hierbei wird der selbe Algorithmus wie bei der<br />
TileNeighborhood Klasse verwendet. Jedes Geometrieobjekt enthält<br />
Informationen über seinen Umfang. Durch diesen Wert kann man ein Rechteck<br />
festlegen, welches das Objekt komplett umschließt. Falls dieses Rechteck sich<br />
nicht im sichtbaren Bereich des Bildschirms befindet, also diesen Bereich auch<br />
nicht schneidet, kann es als nicht sichtbar angesehen werden. Nur die<br />
sichtbaren Geometrieobjekte werden von der Rendererklasse auch auf den<br />
Bildschirm gezeichnet. Dadurch kann bei großen Szenen ein Teil der Objekte<br />
61
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
schon in der Clipping Stufe entfernt werden. Es ergibt sich eine Liste mit den<br />
sichtbaren Bestandteilen der Szene. Diese werden nun von Weltkoordinaten in<br />
Bildschirmkoordinaten umgewandelt. Dabei wird auch die Skalierung der<br />
einzelnen Objekte berücksichtigt. Als Ergebnis erhält man eine Liste mit den<br />
transformierten, sichtbaren Objekten in Bildschirmkoordinaten. Im letzten<br />
Schritt werden dann die einzelnen Objekte auf das Graphics Objekt gezeichnet.<br />
Hierbei werden für alle definierten RenderInfo Objekte die vorhandenen AWT<br />
Funktionen zum Zeichnen auf einen Graphics Canvas verwendet.<br />
Die vom Renderer in der Transformationsphase erstellte Liste mit den<br />
Objekten in Bildschirmkoordinaten bietet noch einen weiteren Vorteil. Sie<br />
kann für das Zuordnen von Objekten zu bestimmten Bildschirmkoordinaten<br />
verwendet werden. Dies dient zum Auswählen und Verschieben von<br />
Fahrzeugen oder Hindernissen per Maus. Dies wird im Editor zum bearbeiten<br />
der Szenenbeschreibung verwendet und im SimulationApplet zur Auswahl<br />
eines Fahrzeuges benutzt.<br />
2.6. XML zur Szenenbeschreibung<br />
2.6.1. Was ist XML?<br />
Die EXtensible Markup Language (XML) gehört, wie HTML auch, zu den<br />
Auszeichnungssprachen. Sie enthält Anweisungen für die Darstellung von<br />
Informationen. Während HTML kaum in der Lage ist, Angaben zu den<br />
Inhalten selbst zu machen, wird in XML Form, Inhalt und die Gestaltung<br />
getrennt behandelt. XML kann man erweitern und an die persönlichen<br />
Bedürfnisse anpassen.<br />
In der Document Type Definition (DTD) wird die Dokumentstruktur (Tags)<br />
und deren Attribute festgelegt. Dies ist jedoch im Gegensatz zu SGML nicht<br />
62
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
zwingend vorgeschrieben. Man unterscheidet zwischen gültigen und<br />
wohlgeformten Dokumenten: Gültig ist ein Dokument dann, wenn es<br />
entsprechend der DTD eine korrekte Syntax aufweist. Man spricht von<br />
wohlgeformt, wenn die Syntax korrekt ist, jedoch keine DTD definiert wurde.<br />
2.6.2. XML Definitionen<br />
XML-Dateien besitzen einige Vorabinformationen für das verarbeitende<br />
Programm. Erster Bestandteil eines XML Documentes ist immer die<br />
Deklaration:<br />
<br />
Anschliessend ist zwingend ein Wurzelelement erforderlich. Ein solches<br />
Element besitzt keine gleichgestellten Elemente. Innerhalb des Wurzelelements<br />
folgen die Elemente zur Darstellung der Informationen. Anders als in HTML<br />
ist XML case-sensitive, d.h. es müssen die Definitionen der Elemente und<br />
deren Attribute unbedingt beachtet werden. Jedes eröffnete Element muß auch<br />
wieder geschlossen werden:<br />
<br />
.....<br />
<br />
Enthält ein Element keine Unterelemente, kann das Tag folgendermaßen<br />
geschreiben werden:<br />
<br />
63
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Attribute werden innerhalb des Tags aufgelistet. Im Gegensatz zu HTML<br />
müssen immer Anführungszeichen für die Attributwerte verwendet werden:<br />
<br />
2.6.3. XML als Szenenbeschreibung<br />
Da eine <strong>Steering</strong><strong>Behaviors</strong>-Szene ein komplexes, aber geordnetes<br />
Objektmodell darstellt, bietet sich an, als Szenenbeschreibung XML zu<br />
verwenden. XML-Dokumente sind leicht zu erstellen und für den Menschen<br />
lesbar und verständlich.<br />
2.6.4. XML-Parser<br />
Zum Parsen von XML-Dokumenten wird der Xerces XML-Parser verwendet.<br />
Xerces ist ein Produkt eines aus insgesamt sieben Unterprojekten des Apache-<br />
XML-Projects. Das Apache-XML-Project verfolgt das Ziel, freie und<br />
professionelle XML-Lösungen anzubieten. Xerces unterstützt das Parsen und<br />
die Generierung von XML-Dokumenten und ist in Java und C++ erhältlich. Es<br />
implementiert die W3C XML und DOM (Level 1 und 2) Standards, sowie den<br />
SAX (Version 2) Standard.<br />
2.6.5. <strong>Steering</strong> XML Referenz<br />
Eine <strong>Steering</strong> Szene<br />
Die einfachste Scenenbeschreibung hat die Form:<br />
<br />
<br />
<br />
64
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Dieses Dokument ist wohlgeformt und es wird keine keine DTD benötigt.<br />
Elemente und Attribute werden in einer <strong>Steering</strong>-Szene grundsätzlich klein<br />
geschrieben.<br />
Eine <strong>Steering</strong> <strong>Behaviors</strong> Szene verwendet das Root-Element .<br />
Das -Elemement besitzt folgende Attribute:<br />
<br />
Attribut Beschreibung<br />
width Die Breite der Szene<br />
height Die Höhe der Szene<br />
image Name des Hintergrundbildes<br />
showgrid Anzeige des Gitternetzes (true/false)<br />
imgsizex Breite des Hintergrundbildes in Pixeln<br />
imgsizey Höhe des Hintergrundbildes in Pixeln<br />
Definition von Fahrzeugen<br />
Zur Fahrzeugsdefinition wird das - Tag verwendet. Für ein<br />
Fahrzeug sind folgende Attribute definiert:<br />
65
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
<br />
Attribut Beschreibung<br />
name Name des Fahrzeugs<br />
x Beschreibt die x-Position des Fahrzeugs<br />
y Beschreibt die y-Position des Fahrzeugs<br />
maxvel Die maximale Geschwindigkeit des Fahrzeugs<br />
maxforce Maximale Steuerungskraft, die auf das Fahrzeug wirken darf<br />
radius Radius des Bounding-Kreises<br />
velx x-Anteil des Geschwindigkeitsvektors<br />
vely y-Anteil des Geschwindigkeitsvektors<br />
scalex Skalierungsfaktor in x-Richtung<br />
scaley Skalierungsfaktor in y-Richtung<br />
color Die Farbe des Fahrzeuges<br />
Eine einfache Fahrzeugdefinition an der Stelle (100,150) ohne Mind sieht<br />
demnach folgendermassen aus:<br />
<br />
Zuweisen von Minds und <strong>Behaviors</strong><br />
Innerhalb des - Tags kann dem Fahrzeug ein Mind und diesem<br />
wiederum ein oder mehrere Verhalten zugewiesen werden. Ein einfaches<br />
SimpleMind wird mit hinzugefügt. Für die Verhalten selbst<br />
sind die Tags nach dessen Namen benannt:<br />
66
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
<br />
Attribut Beschreibung<br />
radius Radius für den Testzylinder<br />
length Die Länge des Testzylinders<br />
influence Einflussfaktor des Verhaltens<br />
<br />
Attribut Beschreibung<br />
frontdistance Länge des vorderen Testvektors<br />
sidex x-Anteil der beiden seitlichen Testvektoren<br />
sidey y-Anteil der beiden seitlichen Testvektoren<br />
influence Einflussfaktor des Verhaltens<br />
<br />
Attribut Beschreibung<br />
frontdistance Länge des vorderen Testvektors<br />
sidex x-Anteil der beiden seitlichen Testvektoren<br />
sidey y-Anteil der beiden seitlichen Testvektoren<br />
influence Einflussfaktor des Verhaltens<br />
<br />
Attribut Beschreibung<br />
steps Anzahl der Schritte für das Erreichen des Ziels<br />
activedistance Maximale Entfernung zum Ziel um das Verhalten zu<br />
aktivieren<br />
target Name des Zielobjekts<br />
influence Einflussfaktor des Verhaltens<br />
67
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
<br />
Attribut Beschreibung<br />
neararearadius Radius, innerhalb dem andere Fahrzeuge gesehen<br />
werden<br />
cohesion Einflussfaktor des verwendeten cohesions-Verhaltens<br />
separation Einflussfaktor des verwendeten separation-Verhaltens<br />
alignment Einflussfaktor des verwendeten alignment-Verhaltens<br />
influence Einflussfaktor des Verhaltens<br />
<br />
Attribut Beschreibung<br />
neararearadius Radius, innerhalb dem andere Fahrzeuge gesehen<br />
werden<br />
influence Einflussfaktor des Verhaltens<br />
lookaheadonly Bei True werden nur die vorderen Fahrzeuge beachtet<br />
<br />
Attribut Beschreibung<br />
neararearadius Radius, innerhalb dem andere Fahrzeuge gesehen<br />
werden<br />
influence Einflussfaktor des Verhaltens<br />
lookaheadonly Bei True werden nur die vorderen Fahrzeuge beachtet<br />
68
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
<br />
Attribut Beschreibung<br />
neararearadius Radius, innerhalb dem andere Fahrzeuge gesehen<br />
werden<br />
influence Einflussfaktor des Verhaltens<br />
lookaheadonly Bei True werden nur die vorderen Fahrzeuge beachtet<br />
<br />
Attribut Beschreibung<br />
activedistance Maximale Distanz zum definierten Ziel innerhalb der<br />
das Verhalten einen Kraftvektor erzeugt<br />
estimatefactor Faktor zur Bestimmung der erwarteten zukünftigen<br />
Position des Ziels<br />
influence Einflussfaktor des Verhaltens<br />
target Name des Zielobjekts<br />
<br />
Attribut Beschreibung<br />
activedistance Maximale Distanz zum definierten Ziel innerhalb der<br />
das Verhalten einen Kraftvektor erzeugt<br />
estimatefactor Faktor zur Bestimmung der erwarteten zukünftigen<br />
Position des Ziels<br />
influence Einflussfaktor des Verhaltens<br />
target Name des Zielobjekts<br />
69
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
<br />
Attribut Beschreibung<br />
x Lokale x-Koordinate des Wander-Kreises<br />
y Lokale y-Koordinate des Wander-Kreises<br />
radius Radius des Wander-Kreises<br />
influence Einflussfaktor des Verhaltens<br />
<br />
Attribut Beschreibung<br />
aktivedistance Maximale Entfernung zum Ziel um das Verhalten zu<br />
aktivieren<br />
posx x-Koordinate des Zielpunkts [deprecated]<br />
posy y-Koordinate des Zielpunkts [deprecated]<br />
target Name des Zielobjekts<br />
influence Einflussfaktor des Verhaltens<br />
<br />
Attribut Beschreibung<br />
arrivedistance Minimale Entfernung zum nächsten Wegpunkt um den<br />
nächsten zu selektieren<br />
influence Einflussfaktor des Verhaltens<br />
Beispiele für eine Vehicle-Definition:<br />
<br />
<br />
<br />
<br />
<br />
<br />
70
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
<br />
<br />
<br />
<br />
<br />
<br />
Definition von Hindernissen<br />
Das -Tag definiert ein Hindernis mit folgenden Attributen:<br />
<br />
Attribut Beschreibung<br />
name Name des Hindernisses<br />
x Beschreibt die x-Position des Hindernisses<br />
y Beschreibt die y-Position des Hindernisses<br />
radius Radius des Bounding-Kreises<br />
scalex Skalierungsfaktor in x-Richtung<br />
scaley Skalierungsfaktor in y-Richtung<br />
angle Drehungswinkel des Hindernisses<br />
color Die Farbe des Hindernisses<br />
Definition der Objektgeometrie<br />
Die Form der Fahrzeuge und Hindernisse kann völlig frei definiert werden.<br />
Verhalten wie ObstacleAvoidance und Containment beachten dabei die<br />
71
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
geometrische Form des Hindernisses.<br />
Die Form eines Objekts wird durch ein Polygon-Shape definiert. Zur<br />
Einleitung einer solchen Formbeschreibung wird das -Tag<br />
verwendet. Die Definition eines Polygons geschieht mit .<br />
Innerhalb dieses Elements werden die Punkte definiert:<br />
<br />
Attribut Beschreibung<br />
x Lokale x-Position des 2D-Punktes<br />
y Lokale y-Position des 2D-Punktes<br />
Eine Formbeschreibung für ein rechteckiges Hindernis kann beispielsweise wie<br />
folgt aussehen:<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
72
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
2.7. <strong>Steering</strong>Factory<br />
2.7.1. Übersicht<br />
Die <strong>Steering</strong>Factory ist ein wichtiger Bestandteil der vorbereitenden<br />
Initialisierung einer Simulation. Sie ist dafür zuständig, eine durch XML<br />
beschriebene Szenenbeschreibung in das von der Simulation verwendete<br />
Objektmodell umzusetzen. Dieses Objektmodell besteht im wesentlichen aus<br />
vier Teilen:<br />
• einer Fahrzeugliste<br />
• einer Hindernisliste<br />
• einem Hintergrundbild<br />
• Szenendetails (z.B. Breite/Höhe einer Szene)<br />
SpecialObjects<br />
XML-Document<br />
<strong>Steering</strong>Factory<br />
Obstacles<br />
Background<br />
Vehicles<br />
SceneSize<br />
Abbildung 46: Ein- und Ausgabeelemente der <strong>Steering</strong>Factory<br />
Aufgabe der <strong>Steering</strong>Factory ist es nun ein XML-Dokument zu parsen und die<br />
oben aufgelisteten Bestandteile einer Szene zur Verfügung zu stellen. Zu<br />
diesem Zweck bestitzt die Factory folgende Zugriffsmethoden:<br />
73
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
• Geometrie getBackground()<br />
Diese Methode liefert eine Geometrie-Instanz, die als Render-Info ein<br />
Tile-Objekt mit dem entsprechenden Hintergrundbild enthält.<br />
• Vector getVehicles()<br />
Liefert eine Fahrzeugliste aller in der Szene enthaltenen Fahrzeuge.<br />
Jedem Fahrzeug sind laut der XML-Beschreibung die entsprechenden<br />
<strong>Behaviors</strong> zugeordnet.<br />
• Vector getObstacles()<br />
Liefert die Liste der Hindernisse. Skalierung, Ausrichtung und die<br />
Form der Hindernisse wird entsprechend der XML-Beschreibung<br />
generiert.<br />
• int getSceneWidth(), int getSceneHeight()<br />
Diese Methoden stellen die Szenenbreite bzw. –höhe zu Verfügung.<br />
Als Eingabeparameter benötigt die <strong>Steering</strong>Factory lediglich den Dateinamen<br />
des XML-Dokuments und eine Referenz zum Neighborhood-Objekt.<br />
2.7.2. Arbeitsweise<br />
Durch Aufruf der Methode createScene() wird die Szene generiert.<br />
Zunächst wird überprüft, ob das XML-Dokument eine <strong>Steering</strong>-Szenerie<br />
beschreibt. Damit dies der Fall ist, muß das Root-Element den Namen<br />
„steering“ besitzen. Anschliessend werden durch die Methode<br />
create<strong>Steering</strong>() die vorhanden Attribute des -Tags<br />
interpretiert und entsprechend gesetzt. Das sind beispielsweise die Attribute<br />
74
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
image, width, height und showgrid.<br />
Nun werden die Hindernisse und Fahrzeuge generiert. Entsprechend der XML-<br />
Beschreibung wird den Fahrzeugen ein Mind und <strong>Behaviors</strong> hinzugefügt. Bei<br />
bestimmten <strong>Behaviors</strong> (z.B. Seek) ergibt sich jedoch ein Problem: Sie<br />
benötigen eine Objektreferenz zu einem anderen Fahrzeug bzw. Hindernis. Aus<br />
diesem Grund wird zuerst eine Hashtabelle aller Fahrzeuge und Hindernisse<br />
generiert. Als Schlüssel wird der Objektname verwendet. Bei der späteren<br />
Generierung eines Verhaltens wird auf diese Hashtabelle zurückgegriffen. Mit<br />
Angabe des Objektnamens erhält man als Ergebnis eine Referenz auf das<br />
entsprechende Objekt.<br />
Hashtable<br />
Name Objektreference<br />
BMW #BMWObject<br />
Audi #AudiObject Seek<br />
target:#AudiObject<br />
…<br />
Hashtable.get("Audi")<br />
BMW<br />
SimpleMind<br />
Audi<br />
SimpleMind<br />
<strong>Behaviors</strong><br />
Abbildung 47: Zuweisung von Objektreferenzen<br />
Das Szenen-Modell wird also zweimal durchlaufen:<br />
1.) Beim ersten Durchgang werden alle Objekte erzeugt und mit jeweiligen<br />
Namen als Schlüssel in einer Hash-Tabelle abgelegt.<br />
2.) Beim zweiten Durchgang werden diese Objekte zusätzlich in<br />
entsprechenden Listen (m_vehicles, m_obstacles) hinterlegt<br />
und die Fahrzeuge mit einem Mind und den zugeordneten Verhalten<br />
erweitert.<br />
75
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Für die Zuweisung der Verhalten werden alle Child-Knoten eines Minds<br />
durchlaufen und entsprechend des Elementnamens eine entsprechende Instanz<br />
erzeugt. Die Attribute werden mit der Methode<br />
setObjectAttributes(ObjectAttributes obj, NamedNodeMap attr)<br />
gesetzt. Diese Methode belegt alle in der Attributliste attr enthaltenen<br />
Attribute durch Aufruf von setAttribute(String name, String<br />
value) mit den in der XML Datei gespeicherten Werten.<br />
ObjectAttributes ist ein Interface, das ermöglicht, einzelnen<br />
Klassenvariablen anhand ihres Names Werte zuzuweisen. Dabei kann jede<br />
Klasse, die dieses Interface implementiert, selbst entscheiden welche Attribute<br />
benötigt werden und wie diese den übergebenen Wert interpretieren.<br />
Das generierte Behavior wird zu einer Behavior-Liste hinzugefügt, die durch<br />
die set<strong>Behaviors</strong>(…)-Methode dem Mind zugewiesen wird.<br />
Formbeschreibungen von Objekten werden durch die<br />
createDescription()-Methode generiert. Diese Methode wird<br />
aufgerufen, sobald ein -Tag gefunden wurde. Die erstellte<br />
Geometrie-Instanz wird dem Parent-Objekt des -Tags<br />
zugerodnet.<br />
Nachdem die <strong>Steering</strong>Factory Klasse die Szene generiert hat, können der<br />
Simulation die Objektlisten und Szenenparameter übergeben werden.<br />
76
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
2.7.3. Erweiterung der <strong>Steering</strong>Factory<br />
Sollte die Szenenbeschreibung mit weiteren <strong>Behaviors</strong> zu erweitern sein, muß<br />
lediglich in der createBehavior()-Methode ein neuer Abschnitt<br />
eingefügt werden, in dem das neue Behavior instanziiert wird und dessen<br />
Attribute gesetzt werden. Das neue Behavior wird anschliessend noch der<br />
Behaviorliste hinzugefügt. Die Implementierung kann wie folgt aussehen:<br />
if (type.equals("newbehavior"))<br />
{<br />
}<br />
NewBehavior b = new NewBehavior();<br />
setObjectAttributes(b, attr);<br />
behaviors.add(b);<br />
2.8. <strong>Steering</strong>Creator<br />
2.8.1. Einleitung<br />
Mit Hilfe von XML-Dokumenten können ziemlich einfach Szenerien<br />
aufgebaut werden. Jedoch sinkt die Übersichtlichkeit mit zunehmender<br />
Komplexität der Szene. Der <strong>Steering</strong>Creator ist ein grafischer Editor der dem<br />
Anwender das manuelle Erstellen oder Bearbeiten eines XML-Dokuments<br />
abnimmt. Man erhält somit bei der Planung den vollen Überblick über das<br />
Aussehen und der Lage der Objekte. Attribute von Objekten, Minds und<br />
<strong>Behaviors</strong> können weiterhin beliebig verändert werden. Die Stärke dieses<br />
Editors liegt in der grafischen Benutzeroberfläche, die es dem Anwender<br />
ermöglicht, mit der Maus oder per manuelle Eingabe Objekte zu platzieren,<br />
skalieren oder zu drehen.<br />
77
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Der <strong>Steering</strong>Creator ist in der Lage XML-Dokumente zu lesen als auch selbst<br />
zu erstellen. Wie bei der <strong>Steering</strong>Factory wird dabei auf Xerces<br />
zurückgegriffen (siehe Abschnitt 2.6.4).<br />
2.8.2. Bedienung des <strong>Steering</strong>Creators<br />
Bildschirmaufteilung<br />
Objektbaum<br />
Menü<br />
Objektinformation Zeichenfläche<br />
Abbildung 48: Die Oberfläche des <strong>Steering</strong>Creators<br />
Der <strong>Steering</strong> Creator besteht im wesentlichen aus 6 Teilen:<br />
• Menü<br />
• Toolbar<br />
• Objektbaum<br />
• Zeichenfläche<br />
• Attribut Editor<br />
• Objektinformationen<br />
Toolbar<br />
Attribut Editor<br />
78
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Menü<br />
Über das Menü ist es möglich, Szenen zu laden, zu speichern bzw. neu zu<br />
erstellen. Außerdem kann über den Menüpunkt “Exit” das Programm beendet<br />
werden.<br />
Der Objektbaum<br />
Abbildung 49: Das Menü<br />
Der Objektbaum stellt die Objektstruktur der Szene dar. Über ihn können die<br />
Verhalten der einzelnen Fahrzeuge verwaltet werden. Im Beispiel wie im Bild<br />
besteht die Szene aus vier Fahrzeugen und zwei Hindernissen. Dem Fahrzeug<br />
mit dem Namen “vehicle1 “ ist ein SimpleMind mit den Verhalten Wander,<br />
Containment und Separation zugewiesen. Um neue Objekte einzufügen steht<br />
ein Kontextmenü zur Verfügung, das durch Klick mit der rechten Maustaste<br />
geöffnet wird.<br />
79
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Die Zeichenfläche<br />
Abbildung 50: Der Objektbaum einer Szenenbeschreibung<br />
Abbildung 51: Die Zeichenfläche<br />
80
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Die Zeichenfläche stellt die Szene grafisch dar. Die Objekte können mit der<br />
Maus beliebig verschoben werden. Die Richtung der Fahrzeuge wird mit dem<br />
roten Angriffsknoten verändert. Hindernisse können mit dem blauen Knoten<br />
skaliert und mit dem roten Knoten gedreht werden. Außerdem stellt die<br />
Zeichenfläche ebenfalls ein Kontextmenü zur Verfügung, mit der Objekte zur<br />
Szene hinzugefügt werden können.<br />
Die Toolbar<br />
Abbildung 52: Toolbar<br />
Die Toolbar enthält die wichtigsten Werkzeuge, die für die Erstellung einer<br />
Szene benötigt werden. Je nachdem welches Objekt im Objektbaum markiert<br />
ist, sind die Schaltflächen aktiviert bzw. deaktiviert.<br />
Das Zoomwerkzeug:<br />
Abbildung 53: Das Zoomwerkzeug<br />
Mit diesem Schieberegler kann in die Szene hinein- bzw. herausgezoomt<br />
werden.<br />
81
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Die Buttons der Toolbar:<br />
Erstellt ein neues Fahrzeug<br />
Fügt ein neues Hindernis in die Szene ein<br />
Entfernt das selektierte Objekt aus der Szene<br />
Klont das Objekt. Bei Fahrzeugen wird das Mind-Objekt mit allen<br />
zugewiesenen Verhalten mitkopiert<br />
Weist dem selektierten Fahrzeug ein Mind zu<br />
Weist einem Mind ein neues Verhalten zu<br />
Simulation Preview. Diese Schaltfläche öffnet ein neues Fenster in<br />
dem die Simulation der aktuell geöffneten Szene dargestellt wird<br />
82
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Der Attribut-Editor<br />
Ein wichtiger Bestandteil des<br />
Creators ist der Attribut-Editor.<br />
Ist ein Objekt bzw. ein Verhalten<br />
markiert, stellt er dessen<br />
Attribute dar, die manuell<br />
bearbeitet werden können. Die<br />
einzelnen Attribute sind in der<br />
<strong>Steering</strong> XML Referenz, Kapitel<br />
2.6.5 auf Seite 64 näher<br />
erläutert. Bestimmte Attribute<br />
werden automatisch angepasst.<br />
Beispielsweise wird das x und y<br />
– Attribut bei Verschiebung<br />
eines Objekts in der<br />
Zeichenfläche automatisch der<br />
neuen Position angepasst. Mit<br />
den Schaltflächen können neue<br />
Attribute hinzugefügt und<br />
vorhandene gelöscht werden.<br />
Tutorial zum Erstellen einer Szene<br />
Abbildung 54: Der Attributeditor<br />
Es soll nun kurz erläutert werden, wie eine Szene erstellt werden kann.<br />
Angenommen man will folgende Szene erstellen:<br />
83
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 55: Szenenaufbau für Queueing<br />
Diese Szene besteht aus drei Hindernissen und einer großen Anzahl an<br />
Fahrzeugen. Sie soll ein Beispiel für Schlangenbildung an einem Engpass<br />
darstellen. Die Fahrzeuge werden mit Hilfe von drei Verhalten gesteuert.<br />
Das Seek-Verhalten zwingt sie, auf das Hindernis außerhalb des definierten<br />
Bereiches zuzusteuern. Da beim Überschreiten der Grenze das Fahrzeug auf<br />
der anderen Seite der Szene platziert wird, kann somit ein unendliches<br />
Wiederholen der Simulation sichergestellt werden.<br />
Damit die Fahrzeuge sich nicht durch die Wände, dargestellt durch zwei<br />
Hindernisse, bewegen, wurde ihnen das Containment-Verhalten zugewiesen.<br />
Dies verhindert das Fahrzeuge sich durch die vorgegebenen Hindernisse<br />
bewegen können. Sie werden gezwungen, sich durch den engen Durchgang zu<br />
zwängen.<br />
Zuletzt erhalten die Fahrzeuge noch ein Separation-Verhalten, wodurch sie<br />
gezwungen werden, einen gewissen Abstand voneinander zu bewahren. Ohne<br />
84
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
dieses Verhalten, würden die Fahrzeuge einfach durch die Engstelle passieren<br />
und dabei einfach alle anderen Fahrzeuge ignorieren.<br />
Um nun die Szene aufzubauen, muß man zuerst mit Hilfe von „File->New“ der<br />
Editor auf die Ausgangsszenerie zurückgesetzt werden. Diese hat eine<br />
vorgegebene Höhe von 480 und eine Breite von 640 Pixel. Für diese<br />
Simulation soll dies auf etwas kleinere Werte verringert werden. Dazu ändert<br />
man die Werte der beiden Attribute „height“ und „width“ auf 360. Um<br />
sicherzugehen, das die Änderungen auch wirklich übernommen worden sind,<br />
sollte man immer auf die „Return“ - Taste drücken um seine Eingaben zu<br />
bestätigen.<br />
Als erstes werden die beiden Hindernisse eingefügt. Diese sollen einen<br />
schmalen Durchlaß bilden. Dazu klickt man auf das „Hindernis hinzufügen“ –<br />
Icon ( ). Man erhält ein Dialogfenster und wählt hier den Typ „rectangle“<br />
aus. Man erhält ein vorgegebenes, rechteckiges Hindernis auf seiner<br />
Zeichenfläche. Mit Hilfe des blauen Kästchens kann man dieses beliebig<br />
skalieren und unter Verwendung des roten Kreises die Ausrichtung ändern. Mit<br />
der Maus kann es beliebig innerhalb der Szene positioniert werden. Das<br />
Hindernis soll nun auf folgende Art platziert werden:<br />
85
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 56: Erstellen des Engpasses<br />
Nachdem der erste Teil des Durchgangs fertiggestellt ist, klickt man auf die<br />
weiße Zeichenfläche, damit kein Objekt markiert ist und benutzt dann<br />
wiederum das „Hindernis hinzufügen“ – Icon um den zweiten Teil des<br />
Durchgangs zu erstellen.<br />
Der nächste wichtige Punkt ist das Festlegen des Ziels für das Seek-Verhalten.<br />
Hierzu benötigt man ein weiteres Hindernis. Dieses platziert man im grauen<br />
Bereich direkt hinter dem geschaffenen Durchgang. Dadurch werden die<br />
Fahrzeuge gezwungen, sich dorthin zu begeben. Sobald sich ein Fahrzeug<br />
innerhalb des grauen Bereichs befindet, also außerhalb der definierten Szene,<br />
wird es automatisch auf der anderen Seite und innerhalb des Erlaubten<br />
Bereichs platziert. Dadurch kann man eine Simulation erstellen, die nicht nach<br />
86
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
jedem Durchgang auf den Anfangszustand zurückgesetzt werden muß. Als<br />
Hindernis wird diesmal ein Kreis verwendet. Diesen kann man ebenso wie die<br />
vorherigen Hindernisse mit dem „Hindernisse hinzufügen“ Befehl einfügen.<br />
Anstelle von „rectangle“ wählt man diesmal „circle“ im Dialogfenster aus. Als<br />
nächstes wird der vorgegebene Name geändert. Dazu klickt man mit der<br />
rechten Maustaste auf den Kreis. Im nun erscheinenden Kontextmenü wählt<br />
man den Menüpunkt „Rename“. Man erhält einen neuen Dialog in dem man<br />
den Namen des Hindernisses wie folgt ändert:<br />
Abbildung 57: Umbenennen des Ziels<br />
Falls noch nicht getan, platziert man jetzt den Kreis in den grauen Bereich in<br />
direkter Linie hinter dem durch die zwei Blöcke gebildeten Durchgang.<br />
Als nächstes erstellt man ein Fahrzeug. Dieses wird mit Hilfe des „Fahrzeug<br />
einfügen“ – Icons ( ) in die Szene eingefügt. Die vorgegebenen Attribute<br />
ändert man wie folgt:<br />
87
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 58: Eigenschaften des Fahrzeuges<br />
Dem Fahrzeug wird nun ein sogenanntes „Mind“ hinzugefügt. Dieses dient zur<br />
Steuerung der einzelnen Verhalten. Der <strong>Steering</strong> Creator stellt zwei<br />
vordefinierte „Mind“ – Klassen zur Auswahl. Das „simple Mind“ summiert die<br />
von den Verhalten erzeugten Kräfte auf und erzeugt daraus den endgültigen<br />
Steuerungsvektor. Das „priority Mind“ akzeptiert nur so lange Kräft von den<br />
Verhalten, bis die maximale Kraft des Fahrzeuges erreicht ist. Alle weiteren<br />
Kräfte der <strong>Behaviors</strong> werden ignoriert. In dieser Simulation wird das „simple<br />
Mind“ verwendet. Durch klicken auf das „Mind hinzufügen“-Icon erhält man<br />
ein Auswahlfenster mit verschiedenen „Mind“-Klassen. Hier wählt man das<br />
„simple Mind“ wie im folgenden Bild gezeigt:<br />
Abbildung 59: Einfügen der "Mind" - Klasse<br />
88
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Nun kann mit der Definition der einzelnen Verhalten begonnen werden. Zuerst<br />
wird das „Seek“-Verhalten hinzugefügt. Dazu klickt man zuerst im<br />
Objektbaum auf das „Mind“ des Fahrzeuges und dann auf das „Verhalten<br />
Hinzufügen“-Icon ( ). Im nun erscheinenden Dialogfenster wählt man das<br />
„Seek“-Verhalten aus:<br />
Abbildung 60: Hinzufügen des Seek - Verhaltens<br />
Die vorgegebenen Eigenschaften des Verhaltens ändert man nun wie folgt ab:<br />
Abbildung 61: Attribute des Seek - Verhaltens<br />
Das „activedistance“-Attribut legt hierbei fest, innerhalb welcher Distanz das<br />
„Seek“ – Verhalten auf das Ziel zusteuern soll. Da die Szene nur 360 Pixel<br />
breit ist, kann durch den Wert 500 garantiert werden, daß das Verhalten<br />
grundsätzlich seine Arbeit verrichtet. Den Wert für das „influence“-Verhalten<br />
reduziert man auf 0.7, d.h. der erzeugte Kraftvektor kann maximal 70% der<br />
maximalen Kraft des Fahrzeuges betragen. In das „target“-Attribut trägt man<br />
89
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
den Namen des gewünschten Ziels ein. In diesem Fall ist es der Name des<br />
kreisförmigen Hindernisses, der als „target“ festgelegt ist.<br />
Um nun das „Containment“-Verhalten dem Fahrzeug zuzuordnen, klickt man<br />
zuerst auf das „Mind“ des Fahrzeuges und anschließend auf „Verhalten<br />
hinzufügen“. Diesmal wählt man das als „Containment (simple)“ bezeichnete<br />
Verhalten aus. Die vorgegebenen Eigenschaften werden nun auf folgende<br />
Werte geändert:<br />
Abbildung 62: Eigenschaften des Containment - Verhaltens<br />
Das „frontdistance“-Attribut legt hier die Länge des nach vorne hin testenden<br />
Vektors fest. Bei der hier definierten Länge erkennt das Fahrzeug Hindernisse<br />
innerhalb einer Distanz von 25 Pixeln. Je größer dieser Wert gewählt ist, desto<br />
früher werden Hindernisse erkannt und darauf reagiert. Die Werte für „sidex“<br />
und „sidey“ verringert man auf 7, dadurch kann das Fahrzeug näher an<br />
Hindernisse heran gesteuert werden.<br />
Zuletzt fügt man das „Separation“-Verhalten hinzu. Die Attribute sollte man<br />
auf folgende Werte festlegen:<br />
Abbildung 63: Attribute für Separation<br />
90
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Durch die Vergrößerung des „neararearadius“-Attributs wird das Fahrzeug<br />
gezwungen einen größeren Abstand von den ihm umgebenden Fahrzeugen zu<br />
halten. Durch das „lookaheadonly“-Attribut beschränkt sich das Fahrzeug<br />
jedoch nur auf die vorderen Fahrzeuge. Die hinteren werden ignoriert. Das ist<br />
nötig, damit die Fahrzeuge nicht von den hinteren Fahrzeugen nach vorne<br />
gedrängt werden.<br />
Bevor nun die weiteren Fahrzeuge erzeugt werden, sollte man nochmals die<br />
Attributwerte der einzelnen Verhalten überprüfen. Falls diese korrekt sind,<br />
klickt man auf das Fahrzeug, um es auszuwählen. Nun kann man mit Hilfe des<br />
„Objekt klonen“ – Icons ( ) eine beliebige Anzahl an Kopien des<br />
Fahrzeuges erstellen. Es ist nur darauf zu achten, das sich die Fahrzeuge<br />
möglichst nicht überlappen, oder sich innerhalb von Hindernissen befinden.<br />
Mit Hilfe des „Objekt klonen“ Befehls kann man schnell eine große Zahl an<br />
Fahrzeugen nach einem vorher definierten Schema erzeugen. Falls man zu<br />
viele Fahrzeuge erstellt hat, kann man die überschüssigen mit dem „Objekt<br />
löschen“ Befehl ( ) wieder aus der Szene entfernen.<br />
Um sich seine erzeugte Szene anzuschauen, klickt man auf den Startknopf (<br />
) und geniest die Show.<br />
91
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
2.8.3. Implementierung<br />
Die Verwaltung der Objekte<br />
Falls einem Mind ein Verhalten zugewiesen werden soll, öffnet sich ein<br />
Dialogfenster mit einer Auswahl von möglichen Verhalten. Genau so bei den<br />
Hindernissen. Woher nimmt der <strong>Steering</strong>Creator diese Informationen? Und<br />
woher übernimmt er Standardeinstellungen von Attributen? Die Anwort auf<br />
diese Fragen lautet: objects.xml<br />
Diese XML-Datei enthält alle Objekte, deren Attribute, Aussehen und evtl.<br />
schon zugewiesenen Unterobjekte. Die Datei besteht aus folgenden Sektionen:<br />
• Vehicles<br />
• Obstacles<br />
• Minds<br />
• <strong>Behaviors</strong><br />
Für jede dieser 4 Sektionen sind Tags definiert. Fügt man beispielsweise ein<br />
neues Fahrzeug hinzu, zeigt eine Dialogbox die unter <br />
definierten Fahrzeuge zu Auswahl an! Auf diese Weise kann durch einfaches<br />
Editieren dieser Datei ein eigenes Profil erstellt werden.<br />
Neben den oben beschriebenen Tags und den Tags der <strong>Steering</strong> XML Referenz<br />
gibt es noch das - Tag. Der eingeschlossene Text wird im Creator im<br />
Hint-Window angezeigt. Auf diese Weise können dem Benutzer des Creators<br />
Infos über das jeweilige Objekt gegeben werden.<br />
Ausschnitte einer object.xml – Datei:<br />
92
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
....<br />
<br />
<br />
<br />
<br />
<br />
......<br />
<br />
<br />
This is a vehicle model.<br />
<br />
<br />
<br />
....<br />
<br />
<br />
Die Klasse ObjectGenerator ist dafür zuständig, diese Datei zu parsen<br />
und die Objekte zu verwalten. Mit den Methoden addVehicle(...),<br />
addMind(...), addObstacle(...), addBehavior(...) wird ein<br />
neues Objekt in den Objektbaum eingefügt. Der ObjectGenerator kümmert sich<br />
dann selbständig darum, ob eine Dialogbox bei mehreren<br />
Auswahlmöglichkeiten benötigt wird und zeigt diese an.<br />
93
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Die EditorCanvas-Klasse<br />
Die Klasse EditorCanvas implementiert die grafische Anzeige und behandelt<br />
die Mausereignisse. Wie im Applet auch, ist für die grafische Ausgabe selbst<br />
der <strong>Steering</strong>Renderer zuständig. Dieser ist für die korrekte Darstellung der<br />
Szene verantwortlich. Außerdem ist er in der Lage, bei Mausklick eine Liste<br />
der angeklickten Objekte zurückzuliefern. Diese Funktion ist die Grundlage für<br />
das Verschieben der Objekte mit der Maus. Jedes darstellbare Objekt ist in die<br />
Klasse GeometrieObjekt eingebettet. Diese enthält einerseits die<br />
Geometrie selbst, andererseits die zusätzlichen Geometrieobjekte, wie<br />
Skalierungs- und Drehungsknoten. Außerdem werden darin objektspezifische<br />
Attribute, die z.B. angeben ob das Objekt selektiert ist, gespeichert. Aus dieser<br />
Klasse erhält EditorCanvas die Informationen, die zur Darstellung des<br />
Objekts benötigt wird. Ein Klick in den Canvas führt zu einer Anfrage an den<br />
<strong>Steering</strong>Renderer, welche Objekte sich an dieser Stelle befinden. Nach der<br />
Verschiebung eines Objektes werden die Attribute x/y-Position durch die<br />
setAttribute(..)-Methode der Klasse <strong>Steering</strong>TreeNode aktualisiert.<br />
Diese Attribute werden an GeometrieObjekt weitergeleitet. Nach einer<br />
visuellen Änderung wird die update()-Methode der GeometrieObjekt-<br />
Klasse aufgerufen, welche die Geometriedaten aktualisiert.<br />
2.9. Simulation Applet<br />
2.9.1. Einleitung<br />
Um die mit dem <strong>Steering</strong> Editor erstellten Szenarien auf einer Webseite<br />
darzustellen, wurde das Simulation Applet entwickelt. Es setzt die vom Editor<br />
gespeicherten XML Dateien wieder in eine Simulation um. Zusätzlich bietet es<br />
94
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
die gleiche Funktionalität wie der Editor um Informationen über die laufende<br />
Simulation zu erhalten.<br />
2.9.2. Bedienung des Simulation Applets<br />
Bildschirmaufteilung<br />
Das Applet ist ein drei Teilebereiche aufgeteilt. Im linken oberen Teil des<br />
Applets befindet sich die Darstellung der Simulation. Im rechten oberen Teil<br />
befindet sich die Anzeige für den Status des aktuell ausgewählten Fahrzeugs.<br />
Im unteren Bereich befinden sich die Steuerelemente für die Simulation.<br />
Simulationsbereich<br />
Im Simulationsbereich befindet sich die Darstellung der Fahrzeuge und<br />
Hindernisse. Fahrzeuge sind als Dreieck definiert, wobei die längere Spitze<br />
immer in Fahrtrichtung zeigt. Hindernisse werden als mehrseitige Polygone<br />
gezeichnet. In diesem Bereich kann der Benutzer ein Fahrzeug mit der rechten<br />
Maustaste auswählen und sich so Informationen über die Verhalten des<br />
Fahrzeuges ausgeben lassen. Diese Informationen werden auf der rechten Seite<br />
des Applets dargestellt. Hier wird jeweils der Name des Verhaltens angegeben<br />
und darunter ein blauer Balken mit der aktuellen Stärke des Verhaltens.<br />
Dadurch läßt sich sehr gut veranschaulichen, welche Verhalten einen<br />
konstanten Einfluß auf die Simulation aufweisen, und welche nur in<br />
bestimmten Situationen ihren Einfluß geltend machen.<br />
95
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 64: Screenshot des Simulation Applets<br />
Mit Hilfe der rechten Maustaste kann der dargestellte Ausschnitt der<br />
Simulation verschoben werden. Der Mauscursor verwandelt sich in ein<br />
Steuerkreuz und durch Bewegen der Maus wird der sichtbare Bereich<br />
verschoben. Eine Verschiebung in den negativen Bereich, oder über den<br />
maximal definierten Bereich hinaus ist nicht möglich.<br />
Steuerelemente<br />
Im unteren Bereich des Applets befinden sich die Steuerelemente mit den<br />
Einstellungen für das Applet.<br />
96
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 65: Die Steuerelemente des Simulation Applets<br />
Der wichtigste Button hier ist der mit „Open project...“ bezeichnete. Mit Hilfe<br />
dieses Steuerelements wird ein weiterer Dialog aufgerufen mit dem man aus<br />
den vorhandenen vordefinierten Simulationen auswählen kann.<br />
Der „Start“ Button dient zum Starten der aktuellen Simulation. Während des<br />
Ablaufs wird der Button mit „Pause“ bezeichnet und pausiert die Simulation.<br />
Mit Hilfe des „Reset“ Buttons kann man die Simulation wieder in den<br />
Ausgangszustand bringen.<br />
Im mittleren Bereich der Steuerelemente befindet sich die „Show Grid“<br />
Checkbox, mit der man die Darstellung eines Gitternetzes über der Simulation<br />
einschalten kann. Die mit „Track selected Vehicle“ bezeichnete Checkbox<br />
schaltet das Tracking des gerade ausgewählten Fahrzeuges ein, oder aus.<br />
Hierbei wird der sichtbare Bereich automatisch so verschoben, daß sich das<br />
Fahrzeug im Mittelpunkt befindet. Falls kein Fahrzeug gewählt ist, hat diese<br />
Checkbox keine Auswirkungen auf die Ansicht. Auf der rechten Seite der<br />
Steuerelemente befindet sich eine Auswahlbox mit den zur Verfügung<br />
stehenden Zoomstufen. Der Benutzer kann hierbei zwischen 50%, 100%, 150%<br />
und 200% Zoom wählen.<br />
Der untere Bereich der Steuerelemente dient einem Anzeigenfeld mit<br />
Hinweisen zum Steuerelement das sich gerade unter der Maus befinden.<br />
Dadurch erhält der Benutzer jederzeit kontextbezogene Hilfe zu den Elementen<br />
des Applet mit denen er interagieren kann.<br />
97
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
3. Abbildungsverzeichnis<br />
Abbildung 1: Szene aus Stanley and Stella in: Breaking the Ice (1987) ............ 5<br />
Abbildung 2: Screenshot aus Dungeon Master 2, Bullfrog Productions Ltd..... 6<br />
Abbildung 3: Kraftvektor beim Seek Verhalten.................................................. 9<br />
Abbildung 4: Kraftvektor beim Arrive Verhalten ............................................. 10<br />
Abbildung 5: Beispiel für eine Fahrstrecke mit dem Wander-Verhalten ......... 12<br />
Abbildung 6: Steuerungsvektor, deren Spitze sich auf dem Kreis befindet ...... 13<br />
Abbildung 7: Berechnung des neuen Steuerungsvektors.................................. 13<br />
Abbildung 8: Verschiedene Einstellungen der Attribute .................................. 14<br />
Abbildung 9: Berechnung des Steuerungsvektors bei Separation.................... 15<br />
Abbildung 10: Berechnung des Steuerungsvektors bei Alignment................... 17<br />
Abbildung 11: Berechnung des Steuerungsvektors bei Cohesion .................... 18<br />
Abbildung 12: Beispiel für gute und schlechte Annäherung durch einen Kreis<br />
.......................................................................................................................... 21<br />
Abbildung 13: Steuerungsvektor zum Ausweichen eines Hindernisses............ 22<br />
Abbildung 14: Beispiele für Kanten, die im 1. Test verworfen werden............ 23<br />
Abbildung 15: Beispiele für Kanten, die im 2. Test verworfen werden............ 23<br />
Abbildung 16: Beispiele für eine Rückkante, die verworfen werden kann....... 24<br />
Abbildung 17: Ausschlusskanten des 4. Tests .................................................. 25<br />
Abbildung 18: Testvektoren beim Containment Verhalten............................... 26<br />
Abbildung 19: Unscharfe Grenzen der Entfernung.......................................... 28<br />
Abbildung 20: Unscharfen Grenzen des Winkels ............................................. 29<br />
Abbildung 21: Diagramm zur Defuzzifizierung................................................ 30<br />
Abbildung 22: Fahrzeug in einer Ausweichsituation ....................................... 30<br />
Abbildung 23: Beispiel einer Fuzzysteuerung .................................................. 31<br />
Abbildung 24: Defuzzifizierung........................................................................ 31<br />
Abbildung 25: Der Steuerungsvektor einer Fuzzy-Ausweichsteuerung ........... 32<br />
Abbildung 26: Problematik bei konkaven Hindernissen .................................. 32<br />
98
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 27: Arbeitsweise des SimpleMinds.................................................. 35<br />
Abbildung 28: Beispiele für die mögliche Kraftverteilung bei PriorityMind... 36<br />
Abbildung 29: Aufteilung der Simulation Klasse ............................................. 37<br />
Abbildung 30: Distanzbestimmung für Neighborhood..................................... 39<br />
Abbildung 31: Symmetrischer Aufbau der Distanzmatrix................................ 40<br />
Abbildung 32: Abfrage bei Hindernissen ......................................................... 41<br />
Abbildung 33: Beispiel für eine Umwandlung in eine auf Tiles basierende<br />
Darstellung ....................................................................................................... 46<br />
Abbildung 34: Screenshot des AlgorithmTest Applets ..................................... 51<br />
Abbildung 35: Die Karteneinstellungen des Applets........................................ 52<br />
Abbildung 36: Der Geschwindigkeitsregler ..................................................... 52<br />
Abbildung 37: Das Algorithmus - Auswahlfeld................................................ 52<br />
Abbildung 38: Das Distanzfunktion - Auswahlfeld .......................................... 53<br />
Abbildung 39: Der Regler für die geschätzen Kosten ...................................... 53<br />
Abbildung 40: Die Steuerungsknöpfe für die Simulation ................................. 54<br />
Abbildung 41: Beispiel eines erzeugten Pfades................................................ 55<br />
Abbildung 42: Screenshot des Regensburg Applets ......................................... 56<br />
Abbildung 43: Die Steuerelemente des Regensburg Applets............................ 57<br />
Abbildung 44: Klassendiagramm für den <strong>Steering</strong>Renderer ........................... 60<br />
Abbildung 45: Ablauf der Koordinatentransformation.................................... 61<br />
Abbildung 46: Ein- und Ausgabeelemente der <strong>Steering</strong>Factory ...................... 73<br />
Abbildung 47: Zuweisung von Objektreferenzen.............................................. 75<br />
Abbildung 48: Die Oberfläche des <strong>Steering</strong>Creators....................................... 78<br />
Abbildung 49: Das Menü.................................................................................. 79<br />
Abbildung 50: Der Objektbaum einer Szenenbeschreibung............................. 80<br />
Abbildung 51: Die Zeichenfläche ..................................................................... 80<br />
Abbildung 52: Toolbar ..................................................................................... 81<br />
Abbildung 53: Das Zoomwerkzeug................................................................... 81<br />
Abbildung 54: Der Attributeditor ..................................................................... 83<br />
99
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
Abbildung 55: Szenenaufbau für Queueing...................................................... 84<br />
Abbildung 56: Erstellen des Engpasses............................................................ 86<br />
Abbildung 57: Umbenennen des Ziels .............................................................. 87<br />
Abbildung 58: Eigenschaften des Fahrzeuges.................................................. 88<br />
Abbildung 59: Einfügen der "Mind" - Klasse................................................... 88<br />
Abbildung 60: Hinzufügen des Seek - Verhaltens ........................................... 89<br />
Abbildung 61: Attribute des Seek - Verhaltens................................................. 89<br />
Abbildung 62: Eigenschaften des Containment - Verhaltens........................... 90<br />
Abbildung 63: Attribute für Separation............................................................ 90<br />
Abbildung 64: Screenshot des Simulation Applets ........................................... 96<br />
Abbildung 65: Die Steuerelemente des Simulation Applets ............................. 97<br />
100
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
4. Literaturverzeichnis<br />
[STO96] Stout, Bryan:<br />
Smart Moves: Intelligent Path-Finding<br />
Game Developer Magazine, October / November 1996<br />
[REY87] Reynolds, Craig W.<br />
Flocks, Herds, and Schools: A Distributed Behavioral Model<br />
ACM SIGGRAPH 1987 Conference Proceedings, Anaheim,<br />
California, July 1987<br />
www.cs.toronto.edu/~dt/siggraph97-course/cwr87<br />
[REY88] Reynolds, Craig W.<br />
Not Bumping Into Things<br />
ACM SIGGRAPH 1988 Conference Proceedings, Anaheim,<br />
California, August 1988<br />
www.red3d.com/cwr/nobump/nobump.html<br />
[REY99] Reynolds, Craig W.<br />
<strong>Steering</strong> <strong>Behaviors</strong><br />
GAME DEVELOPERS CONFERENCE, March 1999<br />
www.red3d.com/cwr/steer<br />
[GRE00] Green, Robin<br />
<strong>Steering</strong> Behaviours<br />
ACM SIGGRAPH 2000 Conference Proceedings, Anaheim,<br />
California, August 2000<br />
[KRÜ00] Krüger, Guido<br />
Java 2 – Handbuch der Java-Programmierung<br />
Addison Wesley, Bonn, Paris, Reading, Massachusetts [u.a.] 2000<br />
101
<strong>Steering</strong> <strong>Behaviors</strong><br />
Autoren: Thomas Feilkas, Christian Schnellhammer<br />
Betreuer: Prof. Jürgen Sauer Regensburg<br />
ISBN 3-8273-1710-X<br />
[SA00] Sauer, Jürgen<br />
Neuronale Netze und Fuzzy-Control-Systeme<br />
Vorlesungsskript im WS2000, FH Regensburg, Fachbereich<br />
Informatik<br />
102