I'm trying to simulate a process that involves 5 mould presses that which undergo tool changes when the number of parts to produce from their current tool is met. Tool changes take 20 minutes to complete and cannot overlap. Presses are modeled with DismantleStation objects and tools are different DismantleLists.
- When a tool change is required, name of the press is added to a tool change queue list
- A tool change method waits for the tool change queue to be populated; when an entry appears, the tool change method references another queue list for what tool to put in the press
- Tool change method waits 20min before starting up the press again after the change, then loops to check if there is another press that requires a tool change
The problem is, I'm not sure how to "properly" keep the tool change method active. Eventually, when the tool change queue list is emptied (when no presses require a change), the while loop in my ToolChange method is no longer true and the method's execution is complete. Eventually a press will be added to the queue list again and the tool change method will have to be re-executed. This is something I'm used to using observers for, to execute a method when the status of something changes, but I can't (I think) in this case because multiple instances of the tool change method will execute as different presses are added to the queue and cause overlap.
Attached is an example model (using 3 presses) of how I have things set up in my main project. Is there a better way to keep the ToolChange method active throughout the simulation?
Solved! Go to Solution.
You can keep ToolChange alive by including a "while true" loop. You would then only need to call ToolChange once (from INIT).
var pressName, nextTool: string
var mouldPress : object
var numShots : integer
// continue to monitor ToolChange queue during simulation
// wait if no presses are queued up for a tool change
waituntil ToolChangeQueue.Dim >= 1
// loop tool change method while there are presses queued up for a tool change (essentially)
while ToolChangeQueue.Dim /= 0
pressName := ToolChangeQueue.top
mouldPress := str_to_obj(pressName)
// update tool status and the InjectionMould object's DismantleList
mouldPress.CurrentTool := nextTool
mouldPress.ShotsReq := numShots
mouldPress.InjectionMould.DismantleList := str_to_obj(pressName + "." + nextTool)
mouldPress.ToolChanges := mouldPress.ToolChanges + 1
mouldPress.RawMaterial.ExitLocked := false
end // end "while true"
Thanks Robert! I realize that the INIT method also remains active throughout the simulation as it is waiting for the ToolChange method to complete its execution. Is there a way I can call a method in INIT so that it runs independent of INIT and not sequential? In my main project, there's an issue where one of the 5 presses is unique and its tool changes need to be handled by a separate ToolChange method. So I need my INIT method to call two always-active ToolChange methods.
To me this sounds rather complicated. The common way to achieve this kind of behavior is through services. It runs fast and is quite simple to model.
First you set the service requirements for your stations, for example "MyTool". The tool is needed for both setting up and for processing. For setting up you also need another service, day "Tool change".
Next you implement two Exporters, one with the service "MyTool" and capacity 5, the other with service "Tool change" and capacity 1.
Finally, insert a Broker. Make sure that the set-up parametets are correct and the Broker is known by your material flow objects.
Also check some of the example models that come with your installation.
If you want to go down the route of looping like you are doing, then what you need to do is something like the following in the init instead.
Doing so will cause the method to start after all currently queued methods have finished, which will be after any of the init methods have finished running.
Instead I would look into the 'Changed' flag on the queues, when the queue is changed then this flag is set to true. It can be observed so would be a good one to use to trigger the method through an observer, at which point you can then check the queue and process anything that is listed in it.
If you are going to go this way then a few things you got to do, first is to say when your running the tool change code, this can be done through a boolean flag and a if statment, second is to reset the Changed flag back to false. See example template below.
if ToolChangeQueue.Changed and not toolChangerRunning toolChangerRunning := true ToolChangeQueue.Changed := false // Code in here (remember to check queue again before exiting your code) toolChangerRunning := false end
Benfit of this, the code wont be running in the background when there is nothing to process.