Die Frameworks für die Steuerungstypen Teilanlagenpoolbelegung und Transfer in/aus Teilanlagenpool haben sich in der neuen INOSIM Version 13 geändert. Die Änderungen bieten einige neue Möglichkeiten, die Steuerungen zu nutzen. Auch wenn es hier neue Funktionen gibt, müssen Sie die Art und Weise, wie Sie diese Steuerelemente schreiben, nicht ändern. Hier zeigen wir Ihnen, was sich geändert hat und was die Vorteile des neuen Verhaltens der Steuerungen sind.
Teilanlagenpoolbelegung
In INOSIM werden Teilanlagenpoolbelegungen genutzt, um zu entscheiden, welche Teilanlage aus einem Pool von einem Teilgrundrezept belegt wird. Bei der neuen Version INOSIM 13 ist die Funktionalität dieser Steuerung verbessert. In INOSIM 12 sah das Framework für die Teilanlagenpoolbelegung noch so aus:
Function Sample_UnitPoolAllocation(proc As ProcedureInstance, u As Unit) As Boolean
' Always allocate the requested unit
Sample_UnitPoolAllocation = True
End Function
Die Steuerung hat zwei Eingabeargumente: Die ProcedureInstance, die die Steuerung aufruft, und die Teilanlage, die belegt werden soll. Der Rückgabewert der Funktion ist ein Boolean, der die Belegung der vorgeschlagenen Teilanlage ermöglicht. Wird die Steuerung aufgerufen, schlägt sie die erste verfügbare Teilanlage (u) im Pool vor. Innerhalb Ihrer Steuerung können Sie entscheiden, ob eine Teilanlage akzeptiert wird oder nicht. Wenn Sie eine Teilanlage ablehnen, wird die Steuerung für die nächste verfügbare Teilanlage im Pool erneut aufgerufen. Dieses Verhalten kann zu vielen Aufrufen der Steuerung führen, selbst wenn Sie sofort wissen, welche Teilanlage zugeordnet werden muss.
In Version 13 wurde dieses Verhalten verbessert. Das neue Framework sieht aus wie folgt:
Sub Sample_UnitPoolAllocation(proc As ProcedureInstance, p As UnitPool, u As Unit, ByRef allocate As Boolean)
End Sub
Als erstes sehen Sie, dass die neue Steuerung, wie andere Steuerungen in INOSIM, ein Sub anstatt einer Funktion ist. Anstatt den Rückgabewert der Steuerung auf true oder false zu setzen, um eine Teilanlage zu akzeptieren oder abzulehnen, wird die Variable allocate verwendet. Die wesentliche Verbesserung besteht darin, dass im ersten Aufruf der Steuerung durch Setzen des PendingUnitsMode der Prozedur für die Mitglieder des Teilanlagenpools entschieden werden kann, ob eine Teilanlage dem Rezept zugewiesen werden kann. Der PendingUnitsMode kann auf puAllocate, puIgnore und puDefault gesetzt werden. Im Fall von puAllocate wird die Teilanlage für die ProcedureInstance verwendet, mit puIgnore wird sie nicht verwendet. Teilanlagen mit dem PendingUnitsMode puDefault werden behandelt wie in Version 12, die Steuerung wird für alle Teilanlagen mit diesem PendingUnitsMode aufgerufen, bis eine Teilanlage für das Rezept akzeptiert wird. Anders als in Version 12, wo u die erste vorgeschlagene Teilanlage im ersten Aufruf ist, kann der erste Aufruf der Steuerung in Version 13 erkannt werden, wenn das Argument u Nothing ist. Zusätzlich wurde der Teilanlagenpool, für den die Steuerung aufgerufen wird, als neues Argument der Steuerung eingeführt. Dies erleichtert den Zugriff auf die Mitglieder des Teilanlagenpools.
Beispiel: Mehrproduktanlage
Betrachten wir, als Beispiel für die Vorteile der neuen Steuerung, eine Mehrproduktanlage. In unserem Beispiel haben wir eine Anlage, die 20 verschiedene Produkte herstellt und für diese Produkte 20 verschiedene Produkttanks hat. Im Modell dauert die Herstellung eines jeden Produktes einen Tag. Nach der Produktion wird das Produkt in LKW abgefüllt. Dieselbe AllocationControl wird für die Auswahl des Tanks innerhalb der Produktion und für die Auswahl des Tanks, der von einem LKW entleert wird, verwendet.
Layout für das Beispiel. Es gibt eine Produktionsstraße, die 20 verschiedene Produkte herstellt. Die Produkte befinden sich in 20 verschiedenen Tanks.
Sowohl die Produktionsaufträge als auch die Abfüllaufträge haben das Material, das sie aktuell produzieren, als Eigenschaft. In diesem Beispiel sind die Produkte und Tanks von 1 bis 20 nummeriert. So kann der Tank entsprechend dem Produktnamen ausgewählt werden. Das Verhalten der Steuerung entspricht Version 12. Für jeden Auftrag wird die Steuerung für die Mitglieder des Tankpools aufgerufen, bis die passende Teilanlage gefunden ist.
Sub Product_Tank_V12(proc As ProcedureInstance, p As UnitPool, _
u As Unit, ByRef allocate As Boolean)
If u Is Nothing Then
Exit Sub
End If
'skipping the first call of the control to have the same behavior as in Version 12
If u.Name="Tank " & Right(proc.Order.Material.Name,Len(proc.Order.Material.Name)-Len("Produkt ")) Then
allocate=True
'If the number of the product name is the same as the number of the tank
Else
allocate=False '
End If
End Sub
Um den richtigen Tank zu finden, testet die Steuerung jedes Mitglied des Teilanlagenpools, das aktuell verfügbar ist. Findet die Steuerung nicht die richtige Teilanlage, z. B. weil diese durch einen anderen Befehl belegt ist, muss die Steuerung erneut aufgerufen werden, wenn eines der Mitglieder des Pools wieder verfügbar wird. Dies kann zu vielen Aufrufen der Steuerung führen, um die richtige Teilanlage zu finden
Der Vorteil des Verhaltens in Version 13 ist nun, dass Sie beim ersten Aufruf der Steuerung entscheiden können, welche Teilanlage für die Zuweisung der Prozedur erlaubt ist. Da der Aufruf nur einmal erfolgt, spart das viel Simulationszeit.
Dim pm As Unit
If u Is Nothing Then 'identifies the first call of the control
For Each pm In p.Members
If pm.Name="Tank " & Right(proc.Order.Material.Name,Len(proc.Order.Material.Name)-Len("Produkt ")) Then
proc.PendingUnitsMode(pm.Name)=PendingUnitMode.puAllocate
'the tank which has the same number as the product is allowed to be allocated
Else
proc.PendingUnitsMode(pm.Name)=PendingUnitMode.puIgnore
'all other tanks are ignored
End If
Next
End If
Innerhalb desselben Modells spart die Verwendung der Steuerung, die das neue Verhalten in Version 13 nutzt, 36% der Simulationszeit in diesem einfachen Modell, wenn ein Produktionsjahr simuliert wird. In komplexeren Modellen könnte dies sogar noch vorteilhafter sein. Darüber hinaus ist es möglich, einer Teilanlage ein Rezept zuzuweisen, die derzeit noch nicht bereit für die Belegung ist, z. B. weil sie noch anderweitig belegt ist. In Version 12 wäre die Steuerung für dieses Rezept jedes Mal aufgerufen worden, wenn eine Teilanlage aus dem Pool wieder zur Verfügung steht. Dann wären alle Teilanlagen aus dem Pool erneut getestet worden.. Was Sie mit benutzerdefiniertem Code erreicht hätten, unterstützt INOSIM 13 jetzt nativ, indem eine feste Teilanlage aus einem Pool einem Rezept zugeordnet wird.
Workaround / Kompatibilität mit V12-Steuerungen
Wenn Sie ein Modell der Version 12 mit Version 13 verwenden möchten oder das Verhalten der Steuerung wie in Version 12 beibehalten möchten, können Sie den ersten Aufruf der Steuerung einfach überspringen, indem Sie am Anfang der Steuerung Folgendes eingeben:
If u Is Nothing Then
Exit Function 'in the first call the control is skipped
End If
Steuerung für Transfer in/aus Teilanlagenpool
Das Verhalten der Steuerung für Transfer in/aus Teilanlagenpool wurde ebenfalls geändert. In einer Transfer-Steuerung können Sie die Senke oder Quelle für die Transferoperationen SimpleInflux, SimpleOutflux oder SimpleTransfer auswählen. In Version 12 sieht das Framework für die Steuerung Transfer in/aus Teilanlagenpool aus wie folgt:
Function Sample_Transfer(cop As OrderOperation, u As Unit, amount As Double, ByRef retry As Boolean) As Unit
' take the first suitable unit
Set Sample_Transfer = cop.SourceSinkUnits(1)
End Function
Die Eingaben der Steuerung sind die aktuelle OrderOperation, die die Steuerung aufruft, die Restmenge des Transfers und der Boolesche Wert retry. Wenn retry auf true gesetzt ist, wird die Steuerung erneut aufgerufen, um eine andere geeignete Teilanlage auszuwählen, falls die Übertragung wegen voller oder leerer Teilanlagen gestoppt wird. Der Parameter u ist Nothing im ersten Aufruf der Steuerung. Bei späteren Aufrufen ist es die aktuell verwendete Teilanlage für den Transfer. Der Rückgabewert der Funktion ist die Teilanlage, die für den Transfer verwendet werden soll.
In der neuen Version wurde das Framework leicht verändert:
Sub Sample_Transfer(p As UnitPool, cop As OrderOperation, amount As Double, ByRef u As Unit, ByRef retry As Boolean)
End Sub
Zunächst einmal ist die Steuerung nicht mehr eine Funktion mit Rückgabewert, sondern eine Prozedur. Der Parameter u ist die Teilanlage, die für den Transfer verwendet wird. Im ersten Aufruf wird die für den Transfer vorgeschlagene Teilanlage im Parameter u gespeichert. Um den ersten Aufruf der Steuerung in Version 13 zu identifizieren, würden Sie verwenden:
If cop.Transfer Is Nothing Then
'first call
Else
'later call
End If
Wenn die Transfer-Eigenschaft nothing ist, können Sie den Parameter u auf die Teilanlage ändern, die für den Transfer verwendet werden soll. Als zusätzlichen Parameter haben Sie den Teilanlagenpool, für den die Steuerung aufgerufen wird.
Beispiel: Edukt-Transfer
Im folgenden Beispiel sollte Edukt A für eine Reaktion aus einem Tankpool entnommen werden. Beim ersten Aufruf der Steuerung wird ein Tank für den Transfer gesetzt. Wenn dieser Tank leer ist, wird die Steuerung erneut aufgerufen und der vollste Tank aus dem Pool ausgewählt, um den Transfer fortzusetzen. Für den nächsten Transfer wird derselbe Tank verwendet, bis er leer ist. Danach soll der nun vollste Tank ausgewählt werden. In Version 12 könnte die Steuerung so aussehen:
Public LastEductTank As Unit 'Global Variable
Function Educt_Transfer(cop As OrderOperation, u As Unit, amount As Double, _
ByRef retry As Boolean) As Unit
Dim pm As Unit
Dim EductTank As Unit
Dim i As Integer
retry=True
If LastEductTank Is Nothing Then
'in the beginning the last tank has to be set to the first member of
'the SourceSinkUnits collection, the pool cannot directly be accessed
Set LastEductTank=cop.SourceSinkUnits(1)
End If
If u Is Nothing Then
'for the first call of the control the tank from the last
'transfer should be used until it is empty
Set EductTank=LastEductTank
Else
'if one tank runs empty, the control is called again and
'the tank with the highest content should be used
Set EductTank=u
For i=1 To cop.SourceSinkUnits.Count
If cop.SourceSinkUnits.Item(i).Contents > EductTank.Contents Then
Set EductTank=cop.SourceSinkUnits.Item(i)
End If
Next
End If
Set Educt_Transfer=EductTank 'set the chosen unit
Set LastEductTank=EductTank 'update the last educt tank used
End Function
In Version 12 kann der Teilanlagenpool, für den die Steuerung aufgerufen wird, nicht direkt angesprochen werden. Stattdessen können Sie auf die SourceSinkUnits-Auflistung der Operation zugreifen. In Version 13 ist es möglich, direkt auf den Teilanlagenpool zuzugreifen, der die Steuerung aufruft.
Public LastEductTank As Unit 'Global Variable
Sub Educt_Transfer(p As UnitPool, cop As OrderOperation, amount As Double, _
ByRef u As Unit, ByRef retry As Boolean)
Dim pm As Unit
Dim EductTank As Unit
retry=True
If LastEductTank Is Nothing Then
'in the beginning the Last Tank has to be set to
'the first member of the unit pool
lastEductTank=p.Members.Item(1)
End If
If cop.Transfer Is Nothing Then
'identifies the first call of the control for this transfer
'for the first call of the control the tank from the
'last transfer should be first used until it is empty
EductTank=LastEductTank
Else
'if one tank runs empty, the control is called again
'and the tank with the highest content should be used
EductTank=u
For Each pm In p.Members
If pm.Contents > EductTank.Contents Then
EductTank=pm
End If
Next
End If
u=EductTank 'set the chosen unit
LastEductTank=u 'update the last Educt tank used
End Sub
Mit der Steuerung in Version 12 war es nicht möglich, auf Informationen über den Teilanlagenpool zuzugreifen, für den die Steuerung aufgerufen wird. Nun ist es nicht nur möglich, auf die Mitglieder dieses Pools zuzugreifen, sondern auch auf andere Eigenschaften wie zum Beispiel seinen Namen.
Workaround / Kompatibilität mit V12-Steuerungen
Wenn Sie ein bestehendes Modell aus Version 12 in Version 13 verwenden möchten, können Sie die alten Steuerungen beibehalten. Geändert werden muss die Art und Weise, zu überprüfen, ob es der erste Aufruf der Steuerung ist. In Version 12 ist u Nothing, aber in Version 13 ist u im ersten Aufruf die erste vorgeschlagene Teilanlage. Um den ersten Aufruf zu identifizieren, können Sie Folgendes verwenden:
If cop.Transfer Is Nothing Then
'first call
Else
'later call
End If
- PDF-Ausdruck zu diesem Tipp & Trick
Fragen?
Möchten Sie mehr über dieses Thema erfahren oder haben weitere Fragen? Bitte kontaktieren Sie uns.
Mehr Tipps & Tricks
Benutzerdefinierte Graphen und Eigenschaften von Graphen in INOSIM Gantt
Custom Curves and Properties Of Curves in INOSIM Gantt In Ihrem Modell wird derselbe Rohstoff in mehreren Tanks aufbewahrt und Sie möchten den gesamten Lagerbestand…
Schichtkalender: Wie Prozeduren während einer Schichtpause unterbrochen werden können
In INOSIM kann die Verfügbarkeit von Ressourcen und Equipment mithilfe von Schichtkalendern ausgedrückt werden. Ein Schichtkalender legt fest, wann ein Equipment verfügbar ist oder wie…
Ausführungsdauer von VBA-Steuerungen messen
In diesem Tipp & Trick geht es um den Einsatz eines VBA Timers zur Messung der Ausführungsdauer von VBA Steuerungen. Um die Perfomance eines Modells…