kramann.info
© Guido Kramann

Login: Passwort:










EmbSyst
1 day_by_day
2 Eingebettete_Systeme
..2.1 Softwareentwicklung
....2.1.1 AgileSoftwareentwicklung
....2.1.2 Verhalten
....2.1.3 Entwurfsmuster
....2.1.4 FuzzyRegler
....2.1.5 Uebung
..2.2 Arduino
....2.2.1 Uebung1
..2.3 Android
....2.3.1 UML
......2.3.1.1 Volumenberechnung
......2.3.1.2 UML_Klassendiagramm
......2.3.1.3 Konstruktor
......2.3.1.4 Statische_Variable
....2.3.2 bluej
....2.3.3 Threads
....2.3.4 Interfacedesign
....2.3.5 Android
......2.3.5.1 Getting_Started
......2.3.5.2 App
......2.3.5.3 Beispielprojekt
........2.3.5.3.1 Richtlinien
........2.3.5.3.2 Anforderungen
........2.3.5.3.3 Layout
........2.3.5.3.4 Projekt_einrichten
........2.3.5.3.5 Refactoring
........2.3.5.3.6 Icon
........2.3.5.3.7 Icon2
........2.3.5.3.8 Kurzanleitung
........2.3.5.3.9 Architektur
........2.3.5.3.10 Anwendungsklasse
......2.3.5.4 Threads
......2.3.5.5 Activities
......2.3.5.6 Was_ist_wo
......2.3.5.7 Regelungssysteme
........2.3.5.7.1 Servo
........2.3.5.7.2 Fahrzeug
......2.3.5.8 ADB_Apps
......2.3.5.9 Veroeffentlichen
......2.3.5.10 Einzelheiten
........2.3.5.10.1 Bildschirmaufloesung
........2.3.5.10.2 Parameter
........2.3.5.10.3 Permission
........2.3.5.10.4 Latenzzeit
......2.3.5.11 Tonerkennung
........2.3.5.11.1 Wahrscheinlichkeitsrechnung
........2.3.5.11.2 Kovarianz_Scilab
........2.3.5.11.3 Java_Threads
........2.3.5.11.4 Java_Reflection
....2.3.6 Processing
......2.3.6.1 Installation
......2.3.6.2 Erste_Schritte
......2.3.6.3 Mechatronik
......2.3.6.4 Bibliotheken
......2.3.6.5 Uebung
......2.3.6.6 Snippets
........2.3.6.6.1 Dateioperationen
........2.3.6.6.2 Bilder
........2.3.6.6.3 GUI
........2.3.6.6.4 Text
........2.3.6.6.5 PDF
........2.3.6.6.8 Maus
........2.3.6.6.10 Zeit
........2.3.6.6.13 Animation
........2.3.6.6.15 Simulation
......2.3.6.7 Referenzen
....2.3.7 Android_Processing
......2.3.7.1 Basics
......2.3.7.2 Einrichten
......2.3.7.3 Crossplattform
......2.3.7.4 sinus
......2.3.7.5 sample
......2.3.7.6 analyse
......2.3.7.7 synthese
......2.3.7.8 Hilfsapps
......2.3.7.9 Eigene_Library
....2.3.8 Processing_VR
....2.3.9 Shapes3D
....2.3.10 TextToSpeech
....2.3.11 Internetprogrammierung
......2.3.11.1 Codegenerierung
......2.3.11.2 PHP_Programmierung
......2.3.11.3 PHP_OOP
......2.3.11.4 Java
......2.3.11.5 UDP
......2.3.11.6 Internetkontrolle
........2.3.11.6.1 Kamerabild
....2.3.12 OSC
......2.3.12.1 Datenaustausch
......2.3.12.2 i2audiolab
......2.3.12.3 Ardour
....2.3.13 Netzwerkprogrammierung
....2.3.14 JNI
....2.3.15 Erweitern
......2.3.15.1 sprich
......2.3.15.2 spiel
....2.3.16 thbvr
....2.3.17 Reflection
....2.3.18 Script
....2.3.19 Java3D
3 Echtzeitprogrammierung
..3.1 Echtzeit
..3.2 Korrektheit
..3.2 Semaphoren
..3.3 Hardware
..3.5 Synchronprogramm
..3.6 Zustandsmaschine
..3.7 Arduino
....3.7.1 Uebung
....3.7.2 RTOS
....3.7.3 Scheduler
....3.7.4 Semaphor
......3.7.4.1 Laufkatze
......3.7.4.2 Java
......3.7.4.3 Semaphor
....3.7.5 Messages
..3.8 Android
....3.8.2 Threads
......3.8.2.1 Java
......3.8.2.2 Synchronisierung
..3.9 Petrinetze
....3.9.1 Installation
....3.9.2 Test
4 KI
..4.1 Unueberwachtes_Lernen
..4.2 Agentensysteme
....4.2.1 Architekturen
......4.2.1.1 Verhalten
......4.2.1.2 Entwurfsmuster
....4.2.2 SUMO
......4.2.2.1 GettingStarted
......4.2.2.2 Antrieb
......4.2.2.3 Sensoren
......4.2.2.4 Zeitbasis
......4.2.2.5 Fernsteuerung
......4.2.2.6 Umsetzung_Fernst
......4.2.2.7 Fernsteuerung3
......4.2.2.10 Umsetzung
......4.2.2.11 Sockelsoftware
......4.2.2.12 Plan
......4.2.2.13 Lernen
........4.2.2.13.1 Parameter
........4.2.2.13.2 Identifikation
........4.2.2.13.3 Java
..4.3 Genetische_Algorithmen
....4.3.1 Heuristiken
....4.3.2 Genalgorithmus
..4.4 Kalmanfilter
....4.4.1 Vorarbeit
....4.4.2 Minimalversion
....4.4.3 Beispiel
5 Bildverarbeitung
..5.1 Gestalttheorie
..5.2 Bildverarbeitung
6 Technische_Systeme
..6.1 Kulturgeschichte
..6.2 Technikphilosophie
..6.3 Anthropozaen
7 Literatur
kramann.info
© Guido Kramann

Login: Passwort:




Testen der Möglichkeiten eines Petrinetzes anhand von "Game of Life"

(EN google-translate)

(PL google-translate)

Mit einem Petrinetz "Game of Life" zu implementieren ist sicher eher ein akademisches Beispiel.

Der Vorteil liegt aber darin, die Korrektheit des Verhaltens leicht mittels einer parallelen Implementierung in Javascript vergleichen zu können.

Außerdem stellt es eine gewisse Herausforderung dar, eine nicht ganz triviale Sache umzusetzen.

Hinweise zu "Game of Life"

Von John Horton Conway 1970 entwickeltes "automatisiertes Brettspiel" (zellulärer Automat), bei dem auf ein 2D Raster an beliebigen Plätzen je ein Chip gelegt wird (Anfangskonfiguration) und nach bestimmten Regeln dann Chips verschwinden oder neu entstehen.

Die Regeln:

  • Sind die Nachbarfelder eines nicht belegten Feldes mit genau drei Chips besetzt, entsteht hier ein neuer Chip.
  • Chips verschwinden, wenn sie weniger als zwei Nachbarn haben.
  • Chips überleben, wenn sie 2 oder drei Nachbarn haben.
  • Chips verschwinden, wenn sie mehr als drei Nachbarn haben.

Das Spiel läuft automatisch iterativ durch: Ausgehend von der aktuellen Chipbelegung wird die sich daraus ergebende bestimmt. Letztere wird in einem Zeitschritt eingetragen und auf diese neue wieder die Regeln angewendet usw.

Siehe auch: https://de.wikipedia.org/wiki/Conways_Spiel_des_Lebens
Übung 1

Erstellen Sie ein "Game of Life" auf einem 5x5-Feld mit HTML5/Javascript.

Mögliche Vorlage unter Verwendung von three.js: gol3d004_drehen.html
Alternative mögliche Vorlage unter Verwendung von three.js: ocean_gol007.html
Übung 2

Erstellen Sie ein ein Petrinetz, das die Regeln von "Game of Life" abbildet und wenigstens einen "Blinker" in einem 3x3-Feld realisiert.

Minimale Musterlösung mit Javascript:
<html>
    <head lang="de">
        <meta charset="iso-8859-1">
        <script language:javascript>

            const KANTE  = 500;
            const BREITE = KANTE;
            const HOEHE  = KANTE;

            const RASTER = 11;
            const BLOCK  = Math.floor(KANTE/RASTER);
            const BLOCKRED  = Math.floor(BLOCK*0.95);
            const OFFSET    = Math.floor((BLOCK - BLOCK*0.8)/2);

            var matrix; 
            var matrix_hilf; 
            var malkontext;

            var MAUS_X = 0;
            var MAUS_Y = 0;

            var SIM = false;
            var ZAEHLER = 0;
            var SLOWDOWN = 2; //>=1 !!
                     //   0 1 2 3 4 5 6 7 8   //Anzahl der Nachbarn
            var regeln = [1,1,0,2,1,1,1,1,1]; //Bei 0..8 Nachbarn: 0=neutral, 1=tot, 2=geburt

            //Hilfsfunktion, die die angeforderten Werte aus der matrix liest, wenn die Ränder verbunden sind.
            function gM(k,i)
            {
                if(k<0)
                    k+=RASTER;
                if(i<0)
                    i+=RASTER;
                k%=RASTER;
                i%=RASTER;

                return matrix[i][k]; 
            }

            function CLEAR()
            {
                    for(var i=0;i<RASTER;i++)
                    {
                        for(var k=0;k<matrix.length;k++)
                            matrix[i][k]=0;
                        for(var k=0;k<matrix_hilf.length;k++)
                            matrix_hilf[i][k]=0;
                    }
            }
 
            function malen()
            {
                //Lazy binding: 
                //Erst, wenn etwas benötigt wird, wird es bereitgestellt.
                if(malkontext==null) 
                {
                    var a = '<canvas id="grafik" width="'+BREITE+'" height="'+HOEHE+'"></canvas>';
                    var b = '<br/><input style="width:200px;text-align:center" type="button" id="START" value="START" onclick="javascript:SIM=true;"/>';
                    var c = '<br/><input style="width:200px;text-align:center" type="button" id="STOP" value="STOP" onclick="javascript:SIM=false;"/>';
                    var d = '<br/><input style="width:200px;text-align:center" type="button" id="CLEAR" value="CLEAR" onclick="javascript:CLEAR();"/>';
                    document.getElementById("BODY").innerHTML = a+b+c+d;
                    malkontext = document.getElementById("grafik").getContext("2d"); 
                    matrix = new Array(RASTER);
                    matrix_hilf = new Array(RASTER);
                    for(var i=0;i<RASTER;i++)
                    {
                        matrix[i] = new Array(RASTER);
                        for(var k=0;k<matrix.length;k++)
                            matrix[i][k]=0;
                        matrix_hilf[i] = new Array(RASTER);
                        for(var k=0;k<matrix_hilf.length;k++)
                            matrix_hilf[i][k]=0;
                    }

                    document.getElementById("grafik").addEventListener("mousemove",verarbeiteMaus,false);
                    document.getElementById("grafik").addEventListener("mousedown",verarbeiteMausklick,false);

                    setInterval(malen,50);
                }

                malkontext.fillStyle = "#8888ff";
                malkontext.fillRect(0,0,KANTE,KANTE);

                for(var i=0;i<RASTER;i++)
                {
                    for(var k=0;k<RASTER;k++)
                    {
                        if(matrix[i][k]>0)
                            malkontext.fillStyle = "#ff0000";
                        else
                            malkontext.fillStyle = "#0000ff";
                        var x = k*BLOCK;
                        var y = i*BLOCK;
                        malkontext.fillRect(x+OFFSET,y+OFFSET,BLOCKRED,BLOCKRED);
                    }
                }           

                if(SIM==true)    
                {
                    ZAEHLER++;
                    if(ZAEHLER%SLOWDOWN==0)
                    {
                        for(var i=0;i<RASTER;i++)
                        {
                            for(var k=0;k<RASTER;k++)
                            {
                                var anzahl_nachbarn = gM(k-1,i-1)+gM(k-0,i-1)+gM(k+1,i-1)  +gM(k-1,i+0)+gM(k+1,i+0)  +gM(k-1,i+1)+gM(k+0,i+1)+gM(k+1,i+1);
                                var r = regeln[anzahl_nachbarn];
                                var w = matrix[i][k];
                               
                                if(w>0 && r==1)
                                    matrix_hilf[i][k] = 0;
                                else if(w==0 && r==2)
                                    matrix_hilf[i][k] = 1;
                                else
                                    matrix_hilf[i][k] = matrix[i][k];
                            }
                        }
                        for(var i=0;i<RASTER;i++)
                            for(var k=0;k<RASTER;k++)
                                matrix[i][k] = matrix_hilf[i][k];

                    }
                }
            }

            function verarbeiteMausklick(event)
            {
                var i = Math.floor(MAUS_Y/BLOCK);
                var k = Math.floor(MAUS_X/BLOCK);

                if(matrix[i][k]>0)
                    matrix[i][k]=0;
                else
                    matrix[i][k]=1;
            }
            function verarbeiteMaus(event)
            {
                MAUS_X = event.offsetX;
                MAUS_Y = event.offsetY;
            }
        </script>
    </head>
    <body style="margin:0; text-align:center">
        <span id="BODY" style="margin:0; text-align:center">
        <input style="width:200px;text-align:center" type="button" id="snap" value="malen" onclick="javascript:malen()"/>
        </span>
    </body>
</html>

Code 0-1: Minimale Musterlösung mit Javascript.

Minimale Musterlösung mit PIPE als Petrinetz:
  • Es gibt vier Bereiche, die in einem Zyklus miteinander verbunden sind.
  • Durch Inhibitoren wird verhindert, dass schon Tokens auf einen Nachfolgebereich übertragen werden, wenn zwischen zwei vorangehenden Bereichen noch Übertragungen stattfinden.
  • Die Bereiche sind: Feld, Zähler, Feld2.
gol_musterloesung_petri.zip - Entwicklungsschritte zu einer rudimentären Petri-Netz basierten Umsetzung eines Blinkers in einem 3x3-Netz mit nicht verbundenen Rändern.
Blinker mit Petrinetz.

Bild 0-1: Blinker mit Petrinetz.