05.10.2013 Aufrufe

Steering Behaviors

Steering Behaviors

Steering Behaviors

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!