• slide

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • slide

     

     

     

     

     

     

     

     

     

     

     

     

     

  • slide

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • slide

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • slide

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • slide

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

× Einleitung 1. Aufbau 3D-Modell 1.a. Einführung Listen und Resources 1.b. Listen 1.c. Listenwerte hinzufügen/entfernen 1.d. Resources 1.e. Mit Objekten verknüpfte Resources 2. Process Flow 2.a. Wofür das Delay? 2.b. Andere Feldtypen 2.c. Bedeutung vom Ausdruck 2.d. SQL-Abfragen von Listen Fazit

Tutorial 3: Resourcen und Listen in Process Flow

Dauer des Tutorials: ca. 20 Minuten

Geeignet für: Fortgeschrittene
(wir empfehlen vorher Tutorial 1 und Tutorial 2)

Ziel:
Nach diesem Tutorial verstehen Sie, wie Sie die Möglichkeiten auszunutzen, welche Resources und Listen in Kombination mit dem Process Flow ermöglichen.

Einleitung

Diese Tutorial soll, anhand eines Beispielmodells, eine Einführung in die Möglichkeiten bieten, die Resourcen und Listen zusammen mit Process Flow bieten. Es werden Grundkenntnisse über das Arbeiten mit FlexSim, insbesondere in den Bereichen 3D-Objekte, Label und Process Flow vorausgesetzt.

Bei dem Beispielmodell, welches wir in diesem Tutorial bauen werden, handelt es sich um einen simplen Fabrikationsprozess. In einer Source werden Items acht unterschiedlicher Typen erzeugt. Diese müssen auf einer von sechs Maschinen bearbeitet werden. Welche Maschine (Processor) welche Typen bearbeiten kann, wird in einer Tabelle festgelegt. Dabei stehen die Zeilen für die verschiedenen Typen und die Spalten für die Maschinen.

Schritt 1 - Aufbauen des 3D-Modells

  1. Ziehen Sie zunächst eine Source und eine Queue in das Modell und verbinden Sie dieser mit einer A-Verbindung. Erstellen Sie in der Source einen On Creation Trigger.
  1. Stellen Sie diesen auf Set Label and Color.
    Erweitern Sie die Bandbreite an möglichen Werten
    auf 1 bis 8.
  1. Fügen Sie als nächstes sechs Processors zum Modell hinzu. Ziehen Sie außerdem eine weitere Queue und eine Sink in das Modell. Ziehen Sie Verbindungen von allen Processors zur zweiten Queue und von dieser zur Sink.

Ihr Modell sollte nun in etwa wie auf dem folgenden Bild aussehen.
(Die genauen Positionen der Objekte sind natürlich Ihnen überlassen).

  1. Fügen Sie alle sechs Processors zu einer Gruppe hinzu.
    (Wir haben diese "Processors" genannt, ein anderer Name ist aber selbstverständlich auch möglich)
  1. Erstellen Sie als nächstes eine globale Tabelle und benennen Sie sie zu "ValidTypes" um.

Diese Tabelle wird festlegen, welcher Processor einen Itemtyp bearbeiten kann. Die Spalten repräsentieren die Processors, die Zeilen die Itemtypen. Jede Zelle gibt an, ob der jeweilige Processer den Typ bearbeiten kann (1) oder nicht (0).

Einführung in Listen und Resources

Bevor wir uns mit dem Process Flow beschäftigen, der die Verteilung der Items übernehmen wird, wollen wir zunächst eine kleine Übersicht über Listen und Resources und die Unterschiede zwischen den beiden bieten.

Listen

Eine Liste ist genau das, was ihr Name vermuten lässt: Sie ermöglicht es Reihe von Werten (Objekte, Items, Token, etc.) in einem Listenformat zu speichern. Diese Daten können dann für Entscheidungsprozesse, wie zum Beispiel das Verteilen von Aufgaben im Modell, verwendet bzw. ausgewertet werden.

Wie werden Werte zu Listen hinzugefügt und von wieder entfernt?

Werte können auf mehreren Wegen auf eine Liste gesetzt (pushed) oder von ihr heruntergenommen (pulled) werden.

  1. Viele Trigger und andere Optionen, wie zum Beispiel Send To Port auf Queues und anderen Fixed Resources, bieten Optionen an, mit denen Werte auf Listen geschrieben oder von ihnen ausgewählt und entfernt werden können.
  1. Es existieren zwei Process Flow-Aktivitäten, die nur diesem Zweck dienen.

  1. Die zugehörigen Befehle List.push und List.pull können in selbsterstelltem Code genutzt werden, um Listen zu verwalten

In diesem Tutorial werden wir die Process Flow-Aktivitäten verwenden.

Eine wichtige Eigenschaft von Listen sind Fields. Jedem Wert auf der List können darüber verschiedene andere Werte zugeordnet werden. Diese können zum Beispiel weitergehende Informationen über den Listenwert enthalten und über SQL-Abfragen zum Filtern und Ordnen der Liste verwendet werden, wenn ein Wert von der Liste gezogen werden soll.

Listen können lokal, also nur in einem limitieren Bereich, wie einem einzelnen Process Flow definiert sein. Oder aber global, sodass von allen Bereichen des Modells aus darauf zugegriffen werden kann.

Sie sind ein mächtiges Werkzeug um Informationen zwischen verschiedenen Teilen des Modells zu übertragen, Aufgaben zu verteilen oder Prozesse zu steuern, an denen mehrere Objekte beteiligt sind.

Resources

Die Process Flow-Aktivität Resource erfüllt eine ähnliche Funktion. In ihrer Standardkonfiguration (Reference -> Numeric) funktioniert sie in etwa wie eine "Liste light". Sie stellt eine limitierte Menge an "Dingen" da, die von einem Token reserviert (acquired) werden können. Jeder Wert der Ressource kann dabei zu jeder Zeit nur von einem Token gleichzeitig genutzt werden.

Dies geschieht mit Hilfe der Acquire Aktivität. Sobald eine Ressource nicht mehr benötigt wird, kann sie über die Release Aktivität wieder freigegeben werden.

Numerische Ressourcen eignen sich daher als schnelle und einfache Möglichkeit einen begrenzten Vorrat an Komponenten für einen Prozess zu implementieren. Ein Beispiel sind zum Beispiel Werkzeuge, die von mehreren Arbeitsplätzen genutzt werden. Man spart sich so die Arbeit, diese Komponenten als tatsächliche Objekte zum Modell hinzufügen zu müssen. Auch eine komplett "virtuelle" Simulation ist so möglich.

Ressourcen, die 3D-Objekte repräsentieren

Ressourcen können auch mit Objekten im 3D-Modell verknüpft sein. Direkt, durch eine fixe Referenz auf das Objekt oder indirekt, durch Anbindung einer Liste oder Gruppe von mehreren Objekten.

In diesem Falle verhält sich die Ressource genauso wie eine Liste. Dies ist auch daran zu erkennen, dass die untere Hälfte der Optionen in ihren Eigenschaften verfügbar werden - die gleichen Optionen, die eine Liste besitzt.

Sie kann weiterhin mit Acquire- und Release-Aktivitäten verwendet werden. Da sie nun aber eine Liste darstellen, können auch die Pull from List- und Push to list-Aktivitäten genutzt werden. Diese stellen weitere Funktionen zur Verfügung, etwa die Unterscheidung zwischen der maximal möglichen und minimal nötigen Menge an Werten, die von der Liste gezogen werden sollen.

Schritt 2 - Erstellen des Process Flows

Nun fügen wir den Process Flow hinzu, der entscheiden wird, auf welchem Processor die Items bearbeitet werden.

Wir bauen die Logik aus Sicher der Items: Jedes Token wird ein einzelnes Item darstellen und versuchen einen, für den Itemtyp passenden, Processor zu reservieren. Diese werden als Teile einer Resource dargestellt.

  1. Fügen Sie einen neuen General Process Flow zum Modell hinzu.
  1. Ziehen Sie eine Event-Triggered Source in das Process Flow-Fenster.
    In ihrem Eigenschaftenfenster, wählen Sie die Pipette neben dem Object Feld aus. Klicken Sie dann im 3D-Fenster auf die Queue, die mit der Source verbunden ist und wählen Sie OnEntry als Triggerevent aus.

Immer wenn jetzt ein Item in die Queue eintritt, wird ein Token erzeugt. Um von diesem aus das Item referenzieren zu können, wollen wir es einem Label auf dem Token zuweisen.

  1. Fügen Sie den gewünschten Labelnamen neben Entering Item im Label Assignment/Match Value Bereich ein und wählen Sie die Option assign im Feld rechts davon aus. Wir haben den kreativen Namen "item" gewählt.
    Wenn Sie das Modell nun laufen lassen, wird für jedes Item ein Token, mit einem Verweis auf das Item im entsprechenden Label, erzeugt.
  1. Fügen Sie eine Delay-Aktivität direkt hinter der event-triggered Source hinzu und stellen Sie eine Dauer von Null Sekunden ein.

Wofür ist dieses Delay gut?

Obwohl es nicht immer unbedingt nötig ist, ist es doch ratsam solche Breathe Wartezeiten nach Ereignistriggern zu setzen. Dies gibt dem entsprechenden Ereignis Zeit komplett ausgeführt zu werden, bevor weitere Aktivitäten ausgelöst werden. In manchen Fällen kann es sonst dazu kommen, dass Logiken, die eigentlich nacheinander ausgeführt werden sollen, gleichzeitig oder in der falschen Reihenfolge ablaufen und so zu Fehlern führen.

Der Name "Breathe" findet in mehreren vorgefertigten Process Flows, wie etwa dem für AGVs, Verwendung. Den Namen haben wir daher von den FlexSim-Entwicklern übernommen.
(Einen Artikel mit weiteren Informationen finden Sie hier: Delay)

  1. Ziehen Sie als nächstes eine Resource in das Process Flow-Fenster. Wählen Sie als Reference, die Gruppe aus, zu der Sie die Processors hinzugefügt haben.
  1. Klicken Sie auf die nun verfügbar gewordene Advanced-Schaltfläche am unteren Rand des Eigenschaftenfensters. Dies öffnet die Listeneigenschaften der Ressource, in denen, unter anderem, weitere Fields hinzugefügt werden können.

  1. Erstellen Sie ein neues Expression-Feld für die Liste, indem Sie im entsprechenden Tab auf das grüne Plus-Symbol klicken.

Dieser Feldtyp erlaubt es einen Flexscript-Befehl einzutippen, welcher ausgewertet wird, sobald ein Wert auf die Liste gesetzt wird oder versucht wird einen Wert von ihr herunterzunehmen. Der Rückgabewert des Befehls wird dann als eigentlicher Wert des Feldes genutzt.

Andere Feldtypen

In der oberen Hälfte der Optionenliste finden Sie viele vordefinierte Felder für Fixed Resources, Flow Items und andere Objekttypen. Die meisten davon sind ebenfalls als Expression-Felder implementiert. Oftmals werden Sie bei der Nutzung von Listen aber auch das simple Label-Feld verwenden. Dies ermöglicht in SQL-Abfragen der Liste den Zugriff auf Labels des Listenobjekts.

  1. Nennen Sie das hinzugefügte Feld "Valid". Es wird angeben, ob der jeweilige Processor (das Listenobjekt) das entsprechende Item bearbeiten kann oder nicht. Tippen Sie das Folgende in das Expression-Feld ein und setzen Sie bei der nebenstehenden Option Dynamic ein Häkchen.

    Table("ValidTypes")[puller.item.Type][Group("Processors").indexOf(value)]

Wenn ein Token versucht einen Processor von der Liste zu ziehen, wird das Valid-Feld für jeden Processor auf der Liste ausgewertet. Es gibt dabei den jeweiligen Wert in der "ValidTypes" Tabelle für die jeweilige Kombination von Itemtyp und Processor zurück. Damit dies funktioniert, muss die Dynamic Option aktiviert sein. Andernfalls wird der puller Wert, nicht als Parameter an die Funktion übergeben.

Wenn ein Token versucht einen Processor von der Liste zu ziehen, wird das Valid-Feld für jeden Processor auf der Liste ausgewertet. Es gibt dabei den jeweiligen Wert in der "ValidTypes" Tabelle für die jeweilige Kombination von Itemtyp und Processor zurück. Damit dies funktioniert, muss die Dynamic Option aktiviert sein. Andernfalls wird der puller Wert, nicht als Parameter an die Funktion übergeben.

Was bedeutet dieser Ausdruck?

Table("TableName")[row][column]
gibt den Wert der Zelle in der genannten Tabelle zurück, die durch die Zeilen- und Spaltennummer bzw. -namen definiert wird.

Wir verwenden in diesem Fall keine festen Zahlen für die Zeile und Spalte, sondern Variablen. puller ist eine Referenz auf das Objekt, welches versucht einen Wert von der Liste zu ziehen. Da wir die Acquire-Aktivität nutzen, ist dies in unserem Fall das Token. (In einer Pull from List-Aktivität, könnten wir selbst angeben, welches Objekt als puller fungiert.) Das zum Token gehörige Item ist im Label "item" referenziert, also verweist puller.item.Type auf den Wert des Typ-Labels auf dem Item. Dieser Wert gibt die Tabellenzeile an.

Group("GroupName").indexOf(object)
gibt den Rang des angegebenen Objektes innerhalb der namentlich genannten Gruppe zurück. value ist ein Verweis auf den Listenwert - in diesem Fall also einer der Processors.

Der Befehl
Group("Processors").indexOf(value)
gibt also den Rang des Processors innerhalb der gleichnamigen Gruppe an. Da wir die Processors in aufsteigender Reihenfolge zur Gruppe hinzugefügt haben, können wir so auf die korrekte Spalte in der "ValidTypes" Tabelle verweisen.

  1. Fügen Sie nun noch ein zweites Expression-Feld namens "Number" zur Liste hinzu. Dieses soll den Rang des Processors angeben; wir verwenden also den gleichen Ausdruck wie zuvor für die Tabellenspalte.

Man könnte alternativ auch auf jedem Processor ein Label erstellen, welches die Nummer angibt. Dies könnte dann durch Hinzufügen eines Label-Feldes zur Liste in SQL-Abfragen genutzt werden.

  1. Fügen Sie als nächstes eine Acquire-Aktivität nach der "Breathe"-Aktivität hinzu. Wählen Sie mithilfe der Pipette die zuvor angelegte Ressource für das Feld Resource Reference aus. Unter Assign To Label können Sie den angeben, wie das Label heißen soll, welches den reservierten Processor referenziert. Wir belassen hier die Standardeinstellung "token.resource".
  1. Tippen Sie den folgenden Ausdruck in das Query/Object/Array-Feld ein:

    WHERE Valid = 1 ORDER BY Number ASC

SQL-Abfragen von Listen

Abfragen in Acquire- und Pull from List-Aktivitäten unterstützen die SQL-Schlüsselwörter WHERE und ORDER BY.

WHERE gibt eine oder mehrere Bedingungen an, die der Wert oder die Listenfelder erfüllen müssen, um von der Liste gezogen zu werden. In unserem muss das "Valid"-Feld den Wert "1" besitzen, der Processor also in der Lage sein, den Itemtyp zu bearbeiten.

ORDER BY ordnet alle in Frage kommenden Listenwerte nach einem oder mehreren Werten der Listenfelder. Dies kann sowohl in aufsteigender (ASC - ascending), als auch absteigender (DESC - descending) Reihenfolge geschehen. Wir tun dies, da die höherrängigen Processors mehr verschiedene Typen bearbeiten können. Indem bevorzugt jene mit niedrigerem Rang genutzt werden, bleiben so viele Optionen wie möglich für weitere Items offen.

  1. Fügen Sie eine Move Object-Aktivität hinzu und konfigurieren Sie diese so, dass das Item auf den, von der Liste gezogenen, Processor bewegt wird.
  1. Fügen Sie außerdem eine Wait for Event-Aktivität hinzu. Diese hält das Token so lange fest, bis das zugehörige Item vom Processor vollständig bearbeitet wurde.

    (Nutzen Sie die Pipette um das OnProcessFinish-Event von einem beliebigen Processor im Modell auszuwählen.)

Die match-Funktion zu nutzen ist in diesem Fall zwar nicht unbedingt nötig, schadet aber auch nicht. Lieber sollte man sie einmal öfter hinzufügen, als sie womöglich zu vergessen, wenn sie tatsächlich gebraucht wird.

Nachdem der Arbeitsschritt abgeschlossen ist, wollen Sie den Processor wieder für weitere Items freigeben.

  1. Dafür fügen Sie eine Release-Aktivität hinzu.
    Da wir den voreingestellen Labelnamen "resource" in der Acquire-Aktvität nicht geändert haben, sind hier keine Anpassungen nötig.
  1. Verbinden Sie den Process Flow zum Schluss mit einer Sink-Aktivität, um das Token des fertiggestellten Items zu löschen.

Der fertige Process Flow sollte in etwa wie folgt aussehen:

Wenn Sie nun das Modell starten, sehen Sie dass Items nur von dazu passenden Maschinen bearbeitet werden. Sollte kein passender Processor frei sein, warten sie stattdessen in der vorgelagerten Queue.

Fazit

Experimentieren Sie, wenn Sie möchten, mit den Werten in der "ValidTypes" Tabelle, um die Funktionalität des Modells zu testen.

Jetzt, da Sie die Grundzüge des Umgangs mit Listen, ihren Feldern und den zugehörigen Abfragen gelernt haben, möchten wir Sie dazu ermutigen, sich vielleicht selbst weitere Modelle zu überlegen, um die Nutzung weiter zu üben.

Zum Beispiel könnten Sie den Process Flow in diesem Modell aus Sicht der Maschinen anstelle der Items bauen, dass also die Maschinen sich passende Teile suchen und nicht umgekehrt.

Statt einer Ressource müssten Sie eine Liste verwenden, die zunächst leer ist und deren Inhalt sich über die Laufzeit des Modells hinweg stets ändert. Die Queue könnte die eintreffenden Items zum Beispiel auf eine globale Liste setzen (entweder in der Send to Port Option oder dem On Entry Trigger). Diese kann dann von Process Flow Liste referenziert werden, von der die Tokens (eines pro Processor) sich mittels einer Pull from List-Aktivität passende Items ziehen.

Falls Sie dabei an einer Stelle nicht weiterkommen, können Sie diesen Fall in dem ebenfalls verfügbaren B-Modell betrachten.
Beide Modelle stehen Ihnen als Download zur Verfügung. Klicken Sie dazu einfach auf die untenstehenden Downloadbuttons.

Bitte zögern Sie nicht uns bei Fragen zum Tutorial zu kontaktieren. Wir schauen uns auch gerne Ihr Modell an!

Dieses können Sie uns bei Bedarf per E-Mail zusenden. Unsere Kontaktdaten finden Sie hier.

Autor: F. Möhlmann