Softwareumgebung: Unterschied zwischen den Versionen

Aus Kicker
Zur Navigation springenZur Suche springen
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 48: Zeile 48:
Um konstante Daten nicht fest im Quellcode einprogrammieren zu müssen, gibt es zwei Konfigurationsdateien.
Um konstante Daten nicht fest im Quellcode einprogrammieren zu müssen, gibt es zwei Konfigurationsdateien.


Als Dateiformat wird XML gewählt. Die erste Datei heißt <code>config.xml</code> und ist im relativen Ordner (gegenüber dem Ausführungsverzeichnis) <code>config/</code> abgelegt. Diese beinhaltet den Dateinamen der zweiten Konfigurationsdatei, die die eigentliche Konfiguration beinhaltet.
Als Dateiformat wird [http://de.wikipedia.org/wiki/Extensible_Markup_Language XML] gewählt. Die erste Datei heißt <code>config.xml</code> und ist im relativen Ordner (gegenüber dem Ausführungsverzeichnis) <code>config/</code> abgelegt. Das Attribut <code>file</code> vom Element <code>startup</code> gibt den Dateinamen der zweiten Datei an. Diese liegt im gleichen Ordner wie die erste Datei und beinhaltet die eigentliche Konfiguration.

Das Zwei-Dateien-System erlaubt es verschiedene Profile, für verschiedene Laufzeitumgebungen (z.B.: verschiedene Server-Adressen der Ballerkennung/SPSchnittstelle) anzulegen. Die <code>file</code>-Elemente innerhalb <code>profiles</code>, geben an, welche weiteren Dateien/Profile zur Verfügung stehen.


==== Aufbau von <code>config/config.xml</code> ====
==== Aufbau von <code>config/config.xml</code> ====


<div style="border: 1px dashed #2F6FAB;">
<source lang="xml">
<source lang="xml" line highlight="4">
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<config>
<config>
Zeile 66: Zeile 69:
</config>
</config>
</source>
</source>
</div>


==== Aufbau von <code>config/[DATEINAME].xml</code> ====
==== Aufbau von <code>config/[DATEINAME].xml</code> ====


Der Aufbau der zweiten Konfigurationsdatei, ist [[Softwareumgebung:Konfigurationsdatei|hier]] erläutert.
<source lang="xml">
<?xml version="1.0" encoding="utf-8"?>
<profile>
<!-- Verbindungsinformationen -->
<connections>
<localhost host="localhost" />
<SPServer host="localhost" port="50000" />
<Ball host="localhost" port="50001" />
<Gui host="localhost" port="60002" />
<KiSPServer host="localhost" port="60000" />
<KiBall host="localhost" port="60001" />
<KiGui host="localhost" port="50002" />
<HighScore host="localhost" port="60020" />
</connections>

<!-- Abmessungen -->
<dimensions>
<field depth="690" breadth="1200">
<goal width="198" />
</field>
<axis>
<one>
<figure pos="221" />
<!--figure min="225" max="473" /-->
<shift value="241" />
<rot min="-170" max="170" />
<pos x="75" />
</one>
<two>
<figure pos="38" />
<figure pos="270" />
<!--figure min="40" max="422" />
<figure min="271" max="653" /-->
<shift value="377" />
<rot min="-170" max="170" />
<pos x="225" />
</two>
<three>
<figure pos="38" />
<figure pos="159" />
<figure pos="280" />
<figure pos="401" />
<figure pos="522" />
<!--figure min="40" max="170" />
<figure min="161" max="291" />
<figure min="281" max="411" />
<figure min="403" max="533" />
<figure min="524" max="654" /-->
<shift value="120" />
<rot min="-170" max="170" />
<pos x="525" />
</three>
<four>
<figure pos="38" />
<figure pos="221" />
<figure pos="404" />
<!--figure min="40" max="288" />
<figure min="222" max="470" />
<figure min="407" max="655" /-->
<shift value="233" />
<rot min="-170" max="170" />
<pos x="825" />
</four>
<distance value="150" />
<offset value="6" />
</axis>
<velocity trans="2000" rot="4285" />
<figure breadth="22" height="72" thickness="11" fielddistance="8" />
<ball diameter="33" toaxisshootable="45" toaxisreachable="64" />
</dimensions>

<!-- Statusse -->
<states>
<values>
<game>
<running default="0" min="0" max="1" />
<computerscore default="0" min="0" max="10" />
<humanscore default="0" min="0" max="10" />
</game>
<global>
<ready default="0" min="0" max="8" />
</global>
<config>
<ready default="0" min="0" max="1" />
</config>
<knowledgebase>
<ready default="0" min="0" max="1" />
</knowledgebase>
<ball>
<ready default="0" min="0" max="1" />
</ball>
<kicker>
<ready default="0" min="0" max="1" />
</kicker>
<axis1computer>
<ready default="0" min="0" max="1" />
<blocking default="0" min="0" max="1" />
<moving default="0" min="-100" max="100" />
<shooting default="0" min="0" max="1" />
<wobbling default="0" min="-1" max="1" />
</axis1computer>
<axis2computer>
<ready default="0" min="0" max="1" />
<blocking default="0" min="0" max="1" />
<moving default="0" min="-100" max="100" />
<shooting default="0" min="0" max="1" />
<wobbling default="0" min="-1" max="1" />
</axis2computer>
<axis3computer>
<ready default="0" min="0" max="1" />
<blocking default="0" min="0" max="1" />
<moving default="0" min="-100" max="100" />
<shooting default="0" min="0" max="1" />
<wobbling default="0" min="-1" max="1" />
</axis3computer>
<axis4computer>
<ready default="0" min="0" max="1" />
<blocking default="0" min="0" max="1" />
<moving default="0" min="-100" max="100" />
<shooting default="0" min="0" max="1" />
<wobbling default="0" min="-1" max="1" />
</axis4computer>
<axis1human>
<blocking default="0" min="0" max="1" />
<moving default="0" min="-100" max="100" />
<shooting default="0" min="0" max="1" />
</axis1human>
<axis2human>
<blocking default="0" min="0" max="1" />
<moving default="0" min="-100" max="100" />
<shooting default="0" min="0" max="1" />
</axis2human>
<axis3human>
<blocking default="0" min="0" max="1" />
<moving default="0" min="-100" max="100" />
<shooting default="0" min="0" max="1" />
</axis3human>
<axis4human>
<blocking default="0" min="0" max="1" />
<moving default="0" min="-100" max="100" />
<shooting default="0" min="0" max="1" />
</axis4human>
<ballpos>
<computerpossession default="0" min="0" max="1" />
<humanpossession default="0" min="0" max="1" />
<speed default="0" min="0" max="100" />
</ballpos>
<ballpostoaxis1computer>
<holdable default="0" min="0" max="10" />
<passable default="0" min="0" max="10" />
<shootable default="0" min="0" max="10" />
<handable default="0" min="0" max="10" />
</ballpostoaxis1computer>
<ballpostoaxis2computer>
<holdable default="0" min="0" max="10" />
<passable default="0" min="0" max="10" />
<shootable default="0" min="0" max="10" />
<handable default="0" min="0" max="10" />
</ballpostoaxis2computer>
<ballpostoaxis3computer>
<holdable default="0" min="0" max="10" />
<passable default="0" min="0" max="10" />
<shootable default="0" min="0" max="10" />
<handable default="0" min="0" max="10" />
</ballpostoaxis3computer>
<ballpostoaxis4computer>
<holdable default="0" min="0" max="10" />
<passable default="0" min="0" max="10" />
<shootable default="0" min="0" max="10" />
<handable default="0" min="0" max="10" />
</ballpostoaxis4computer>
<ballpostoaxis1human>
<holdable default="0" min="0" max="10" />
<passable default="0" min="0" max="10" />
<shootable default="0" min="0" max="10" />
<handable default="0" min="0" max="10" />
</ballpostoaxis1human>
<ballpostoaxis2human>
<holdable default="0" min="0" max="10" />
<passable default="0" min="0" max="10" />
<shootable default="0" min="0" max="10" />
<handable default="0" min="0" max="10" />
</ballpostoaxis2human>
<ballpostoaxis3human>
<holdable default="0" min="0" max="10" />
<passable default="0" min="0" max="10" />
<shootable default="0" min="0" max="10" />
<handable default="0" min="0" max="10" />
</ballpostoaxis3human>
<ballpostoaxis4human>
<holdable default="0" min="0" max="10" />
<passable default="0" min="0" max="10" />
<shootable default="0" min="0" max="10" />
<handable default="0" min="0" max="10" />
</ballpostoaxis4human>
</values>
<links><!-- In Config eine Funktion schreiben die die Verlinkungen zurückgibt -->
<game></game>
<global>
<updates group="game" state="running" />
</global>
<config>
<updates group="global" state="ready" />
</config>
<knowledgebase>
<updates group="global" state="ready" />
</knowledgebase>
<ball>
<updates group="global" state="ready" />
</ball>
<kicker>
<updates group="global" state="ready" />
</kicker>
<axis1computer>
<updates group="global" state="ready" />
</axis1computer>
<axis2computer>
<updates group="global" state="ready" />
</axis2computer>
<axis3computer>
<updates group="global" state="ready" />
</axis3computer>
<axis4computer>
<updates group="global" state="ready" />
</axis4computer>
<axis1human></axis1human>
<axis2human></axis2human>
<axis3human></axis3human>
<axis4human></axis4human>
<ballpos></ballpos>
<ballpostoaxis1computer></ballpostoaxis1computer>
<ballpostoaxis2computer></ballpostoaxis2computer>
<ballpostoaxis3computer></ballpostoaxis3computer>
<ballpostoaxis4computer></ballpostoaxis4computer>
<ballpostoaxis1human></ballpostoaxis1human>
<ballpostoaxis2human></ballpostoaxis2human>
<ballpostoaxis3human></ballpostoaxis3human>
<ballpostoaxis4human></ballpostoaxis4human>
</links>
</states>
<!-- Schusswinkel - Offset -->
<shootoffset>
<byRotation>
<shoot angle="0" offset="0" />
<shoot angle="10" offset="18" />
<shoot angle="20" offset="20" />
<shoot angle="30" offset="22" />
<shoot angle="45" offset="25" />
</byRotation>
<byTranslation>
<shoot angle="50" offset="20" />
<shoot angle="60" offset="17" />
<shoot angle="70" offset="15" />
<shoot angle="80" offset="13" />
<shoot angle="90" offset="0" />
</byTranslation>
</shootoffset>

<!-- Startpositionen -->
<!--startpos>
<axis>
<one>
<pos pos="124" angle="0" />
<velo trans="800" rot="800" />
<shoot exec="false" />
</one>
<two>
<pos pos="191" angle="0" />
<velo trans="800" rot="800" />
<shoot exec="false" />
</two>
<three>
<pos pos="65" angle="0" />
<velo trans="800" rot="800" />
<shoot exec="false" />
</three>
<four>
<pos pos="124" angle="0" />
<velo trans="800" rot="800" />
<shoot exec="false" />
</four>
</axis>
<ball x="0" y="0" />
<score human="0" computer="0" />
</startpos-->

<!-- Sonstiges -->
<other>
</other>
</profile>
</source>


== Interprozesskommunikation ==
== Interprozesskommunikation ==

Version vom 27. November 2012, 08:07 Uhr

In Bearbeitung!!!

Um den Kicker zu betreiben, sind drei grundlegende Software-Komponenten nötig. Die SPS (TwinCAT), die Ballerkennung und die Spielsteuerung. Um den Zugriff auf die SPS, für die anderen Programme zu vereinfachen, gibt es die SPSchnittstelle.

TwinCAT

TwinCAT ist eine Software-SPS der Firma Beckhoff Automation. Sie bietet sowohl die Funktionalität einer SPS, sowie einer numerischen Bahnregelung (NC), zur Regelung der Elektromotoren. TwinCAT läuft unter Windows XP und erweitert dieses um eine echtzeitfähige Laufzeitumgebung. Es wird TwinCAT NC PTP (Numerical Control, Point-To-Point) in der Version 2.10.0 verwendet. Als Schnittstelle zur SPS, steht ADS zur Verfügung.

Die Programmierung erfolgte in "Strukturierter Text" und ist im SVN abgelegt. Programmierer war hier Karsten Schätzle, die Umsetzung geschah 2010 als Teil der Diplomarbeit "Entwicklung, Aufbau und Programmierung eines mehrachsigen Antriebskonzeptes mit überlagerten Bewegungen".

Visualisierung von TwinCAT

SPSchnittstelle

Um den Zugriff auf die SPS zu vereinfachen, wurde die SPSchnittstelle programmiert. Sie übersetzt die ADS-Schnittstelle und stellt ein UDP-Server dar, um eine einheitliche Interprozesskommunikation im Projekt zu gewährleisten.

Die Programmierung erfolgte in C/C++ und ist im SVN abgelegt. Programmierer war hier Karsten Schätzle (erste Version, mit TCP-IP), die Umsetzung geschah 2010 als Teil der Diplomarbeit "Entwicklung, Aufbau und Programmierung eines mehrachsigen Antriebskonzeptes mit überlagerten Bewegungen". Die Umstellung auf UDP erfolgte von Scharel Clemens.

Ballerkennung

Die Ballerkennung ermittelt die Ballposition auf dem Spielfeld mit Hilfe von zwei Embedded-Kameras im 10ms-Takt. Die Position des Balls wird mittels einer Visualisierung am Bildschirm dargestellt und für weitere Programme per UDP-Server zur Verfügung gestellt.

Die Programmierung erfolgte in C/C++ und ist im SVN abgelegt. Programmierer war hier Manuel Zimmermann (erste Version, mit Shared Memory), die Umsetzung geschah 2009 als Teil der Diplomarbeit "Computergestützte visuelle Positionsbestimmung durch Triangulation in zwei Dimensionen". Die Umstellung auf UDP erfolgte von Manuel Zimmermann und Scharel Clemens.

Visualisierung der Ballerkennung

Spielsteuerung

Die Spielsteuerung, ist das Programm, welches die Spielzüge bestimmt. Sie berechnet, mit Hilfe der Ball- und Spielstangenpositionen, welche Bewegungen als nächstes auszuführen sind. Sie stellt also die künstliche Intelligenz dar.

Die Programmierung erfolgte in C++ und ist im SVN abgelegt. Programmierer war hier Scharel Clemens, die Umsetzung geschah 2012 als Teil der Diplomarbeit "Konzeption einer Softwareumgebung zur intelligenten Ansteuerung eines automatisierten Tischkickers".

Visualisierung der Spielsteuerung
(wurde mittlerweile in ein eigenes Programm ausgelagert)

Dokumentation

Der Quellcode ist recht ausführlich kommentiert und fast vollständig mit Doxygen-Kommentaren versehen. Aus dem Quellcode lässt sich mit Hilfe von Doxygen eine vollständige Dokumentation der Klassen und Prozeduren extrahieren. Das entsprechende Doxyfile liegt im gleichen Ordner wie der Quellcode. Die Ausgabe erfolgt in drei Formaten: html, latex/pdf und rtf.

Programmablauf

Aus der Dokumentation und des Quellcodes alleine, ist der Programmablauf nur schwer ersichtlich. Deshalb wird dieser hier, mit Hilfe von Sequenzdiagrammen beschrieben. Der allgemeine Programmablauf, ist diesem Sequenzdiagramm zu entnehmen. Es erläutert, welche Klasse wann erzeugt und welche Memberfunktionen wann aufgerufen werden. Die eigentliche Funktionalität (Fahrbefehle für die Spielstangen) befindet sich in der Funktion runAgent(), der Klasse AxisAgent. Es gibt vier Instanzen dieser Klasse, und somit 4 Threads, in denen die Funktion runAgent() parallel ausgeführt wird. Jede Instanz ist für eine Spielstange zuständig.

Die Sequenzdiagramme sind ebenfalls im Microsoft Visual Studio-Format im SVN beim Quellcode abgelegt.

Konfiguration

Um konstante Daten nicht fest im Quellcode einprogrammieren zu müssen, gibt es zwei Konfigurationsdateien.

Als Dateiformat wird XML gewählt. Die erste Datei heißt config.xml und ist im relativen Ordner (gegenüber dem Ausführungsverzeichnis) config/ abgelegt. Das Attribut file vom Element startup gibt den Dateinamen der zweiten Datei an. Diese liegt im gleichen Ordner wie die erste Datei und beinhaltet die eigentliche Konfiguration.

Das Zwei-Dateien-System erlaubt es verschiedene Profile, für verschiedene Laufzeitumgebungen (z.B.: verschiedene Server-Adressen der Ballerkennung/SPSchnittstelle) anzulegen. Die file-Elemente innerhalb profiles, geben an, welche weiteren Dateien/Profile zur Verfügung stehen.

Aufbau von config/config.xml

<?xml version="1.0" encoding="utf-8" ?>
<config>
    <!-- Konfiguration die beim Programmstart geladen werden soll -->
    <startup file="default.xml" />
    
    <!-- Alle verfügbaren Konfigurationsdateien -->
    <profiles>
        <file name="default.xml" />
        <file name="localhost.xml" />
        <file name="localhost_kickerAndBallAtProck-Kicker.xml" />
    </profiles>
</config>

Aufbau von config/[DATEINAME].xml

Der Aufbau der zweiten Konfigurationsdatei, ist hier erläutert.

Interprozesskommunikation

Der Begriff "Interprozesskommunikation" wird nachgehend mit "IPC" abgekürzt.

Einleitung

Für jede Teilaufgabe gibt es beim Kicker ein eigenständiges Programm.

Beispiel der IPC zwischen Ballerkennung und Spielsteuerung

Dieses Sequenzdiagramm beschreibt den sequentiellen Ablauf der IPC zwischen Spielsteuerung und Ballerkennung, innerhalb der Spielsteuerung.