View Full Version : Double load handling ASRS
Paul Dowling
10-25-2007, 12:59 AM
Hello All,
I'm trying to create a double load handling ASRS and am struggling to find a simple solution. The basic problem is that the inbound totes (shown in attached model as blue) get mixed up with the outbound items (red) making the whole system really innefficient. For example, the ASRS (on occasion) will collect 1 inbound tote, go into the system and collect an outbound tote, and return it to the outgoing queue before putting away the inbound tote.
To my knowledge i can't use batching as I still want the ASRS to collect a single tote (from the inbound queue) and put it away if the isn't 2 there.
If this doesn't make sense, in conclusion i'm looking for an efficient double load handling crane- and in my understanding this would involve not mixing up ingoing and outgoing on a single crane trip as can happen with my model.
Any help would be much appreciated.
Regards
Paul
tobias.biemueller
10-25-2007, 01:53 AM
Hi Paul,
if i understand the problem right, you want to handle two items on one ASRS-Vehicle.
I solved this problem with own written Tasksequences.
i.e.:
// REFERENCE TO NODES
treenode Rack = tonode(rackid);
treenode Greifer = centerobject(Rack, Greiferid);
treenode Ausgang = outobject(Rack,Greiferid);
treenode newtasksequence;
treenodearray t_item = makearray(2);
// ADD ITEMS TO REFERENCES
t_item[0] = tonode(item1);
t_item[1] = tonode(item2);
// ADD EMPTY TASKSEQUENCE IN VEHICLE
newtasksequence = createemptytasksequence(Greifer , 0 ,0 );
// INSERT TRAVEL TASK TO RACK
inserttask(newtasksequence, TASKTYPE_TRAVEL, Rack,NULL);
// INSERT FRLOAD TASKS FOR THE ITEMS WHICH SHOULD BE LOADED
for(int Counter = 1; Counter <= CapacityGreifer ; Counter++)
{
inserttask(newtasksequence, TASKTYPE_FRLOAD, t_item[Counter-1], Rack,1);
}
// INSERT TRAVEL TASK TO CONVEYOR
inserttask(newtasksequence, TASKTYPE_TRAVEL,Ausgang , NULL);
// INSERT FRUNLOAD TASKS FOR THE ITEMS WHICH SHOULD BE UNLOADED
for(int Counter1 = 1; Counter1 <= CapacityGreifer ; Counter1++)
{
inserttask(newtasksequence, TASKTYPE_FRUNLOAD, t_item[Counter1-1], Ausgang , 1);
};
// DISPATCH THE NEW TASKSEQUENCE
dispatchtasksequence(newtasksequence);
Hope this would be a little bit helpful for you.
Best Regards
Tobias
Paul Dowling
10-25-2007, 07:08 PM
Thanks tobias.
I actually tried doing it this way myself but had some problems- I think to do with referencing the items. To my mind all i had to do was :
- use a standard tasksequence
- remove the break (i assume this is responsible for trips in and out of the rack to be mixed up)
- add a conditional if statement, that if the content of the rack (or the inbound queue) is > 1 it trieds to pick up and unload a second items. For the task sequences i referenced the 2 items using rank (current, 1) and rank (current, 2).
It ended up crashing flexsim (i didn't save before), but the code was something similar to:
inserttask(ts,TASKTYPE_TRAVEL,current,NULL);
inserttask(ts,TASKTYPE_FRLOAD,rank(current,1), item,current,port);
if (content(current) > 1){inserttask(ts,TASKTYPE_FRLOAD,rank(current,1), item,current,port);inserttask(ts,TASKTYPE_FRLOAD,r ank(current,2), item,current,port);inserttask(ts,TASKTYPE_TRAVEL,o utobject(current,port),NULL);inserttask(ts,TASKTYP E_FRUNLOAD,rank(current,1),outobject(current,port) ,opipno(current,port));inserttask(ts,TASKTYPE_FRUN LOAD,rank(current,2),outobject(current,port),opipn o(current,port));}else{inserttask(ts,TASKTYPE_FRLO AD,rank(current,1), item,current,port);inserttask(ts,TASKTYPE_TRAVEL,o utobject(current,port),NULL);inserttask(ts,TASKTYP E_FRUNLOAD,rank(current,1),outobject(current,port) ,opipno(current,port));}
Cliff King
10-26-2007, 06:49 PM
Without looking into your problem too deeply, let's see if I can give you some quick advice in the short time I have before heading off for the weekend...
It looks like you're making the mistake of referencing flowitems in your task sequence code that do not exist at the time the task sequence will be created. This is the mistake everyone makes, so don't feel bad. It's easy to forget that the inserttask statements get evaluated when the tasksequence is first created and NOT when the ASRSvehicle begins the task. If you want to evaluate code at the time the task begins, because you don't know what flowitems will be available at that time, then use the task called TASKTYPE_CALLSUBTASKS. It's an advanced task type that you'll want to read up on in the help before using it. It was designed just for this sort of situation.
Another option for tackling this problem might be to use a sophisticated "Break To Requirement" for the ASRSvehicle because it is a field that will be evaluated after the vehicle loads the first item. The code would need to return a 1 only for those tasksequences associated with an item that it is okay to double load. Remember the vehicle's maximum capacity needs to be 2 for this field to even be evaluated. The nice thing about this option is that you only have to write code in one place plus you get to use standard "Use Transport" options.
Paul Dowling
11-13-2007, 07:12 PM
Hi Cliff,
Thanks for that. I was trying to solve all my issues in the tasksequence creation and hadn't considered the break to requirement in the crane (which is now doing the job perfectly by only allowing the crane to break to tasks originating at the same port).
So, my current understanding of tasksequences is:
- tasksequences are generated in a TaskExecuter as soon as the task becomes possible (item arrived, IO ports open)
- This is stored in a list of tasks within the TE. Some smart logic is used concerning task prioritisation (eg if a TE has to travel a given route then it will perform any tasks that are basically "on the way").
- Some smart logic is also used concerning joining trips together if the TE has a capicity greater than 1.
- We can define this logic using various parameters/ functions in the Fixed resources and the Task executer concerned
Just putting my no doubt very basic understanding out in there in case i have fundamentally misunderstood anything. Anyone, feel free to add or correct.
Cheers
Paul
Tom David
12-14-2007, 03:02 AM
Paul,
I am not sure if it will be helpful for you, but I posted a model called Sample_ASRSVehicleDoubleCycle_TD (http://www.flexsim.com/community/forum/downloads.php?do=file&id=81) some days ago under Downloads / Models / User Concept or just click here on the model name and follow the link.
Hopefully this model can give you some hints and ideas how to solve such a task.
Good success
tom the (A)tom
Paul Dowling
05-06-2008, 12:33 AM
Hi All,
Thanks to the feedback given i have made quite a bit of progress on this, using a fairly simplistic break to requirement. Nothing as complex as the aforementioned model (afraid its a bit beyond my skill level at the moment Tom), but it seemed to be doing the job!
Unfortuneately I've run into some more difficulties. By setting the breakto requirement to "same loadstation" i thought i would eliminate the occurance of the Double Load Handling Device (carrying 2 outbound items) dropping off one item at the outfeed and then going to the infeed to collect an item from the infeed, still carrying an outbound item (clearly not an operationally sensible thing to do).
However, I've run into just this problem. I noticed it was happening when i raised the priority on the inbound queue (as i wanted to be able to prioritise transport in this direction when needed).
I have attached a model showing this. To summarise:
- I don't want the blue and red items on the ASRS at the same time (which does happen in the attached model given enough time)
- I would like to be able to stop collecting red items and putaway the blue for a while (still using full double load handling capability).
I hope this makes sense...
Thanks
Paul
PS- Using 4.01
Cliff King
05-06-2008, 07:02 PM
Paul,
I'm going to add comments to your previous post regarding tasksequences:
- tasksequences are generated in a TaskExecuter as soon as the task becomes possible (item arrived, IO ports open)
When the "Use Transport" box is checked on an object, a tasksequence is created and dispatched at the time the flowitem is free to be moved to the downstream object (i.e. the flowitem has been released AND the downstream object has accepted it). The default tasksequence for this situation is composed of the following task types: travel, load, break, unload, travel.
- This is stored in a list of tasks within the TE. Some smart logic is used concerning task prioritisation (eg if a TE has to travel a given route then it will perform any tasks that are basically "on the way").
The tasksequence is dispatched to whatever object (Dispatcher or TaskExecuter) you referenced in the "Request Transport From" field at the time I mentioned above. The Dispatcher will pass the tasksequence onto any available TE's connected to its output ports. If the tasksequence is dispatched directly to a TE, the TE will queue it up just like a Dispatcher does (after all a TE is a subclass of the Dispatcher) if it's currently busy, or it will begin executing the list of tasks in the tasksequence immediately if it is already available. There is no default that causes a TE to perform tasks "along their way". TE's simply perform the tasks in the order they are listed in the tasksequence. Using the "Break To Requirement" on a TE with sufficient capacity will cause the TE to stop performing tasks when the break task is encountered, put that partially completed tasksequence back in its queue of tasksequences, and start another tasksequence.
- Some smart logic is also used concerning joining trips together if the TE has a capicity greater than 1.
The TE is never doing two tasksequences at the same time; when it is working on one tasksequence, it puts the other one back in its tasksequence queue. It only switches back to the first tasksequence after completing the second tasksequence. If the unload station is at the same location as the first item, then the TE will not need to go anywhere during the second travel task and it will begin the unload task immediately after unloading the first item.
- We can define this logic using various parameters/ functions in the Fixed resources and the Task executer concerned
Not sure what you mean by this one, but yes you can create your own tasksequences and fill them up with any tasks you want to, and you can dispatch the tasksequence at any time and to TE or Dispatcher you want to. We've included a wizard that helps you create tasksequences without using code that you should check out. It is accessed through the Tools>Global Task Sequences menu.
Cliff
Paul Dowling
05-06-2008, 10:19 PM
Thanks Cliff, that clears things up a lot. It also has given me a solution to my problem!
What I didn't realise was that a break causes the last bit of the current TS to be put back on the queue (presumeably before any TS's with the same priority, hence my model working until now)- I guess i thought it would resume when the breakto task finished or something. This caused the higher priority infeed tasks to outrank the unfinished TS (the one that still had unloading to do).
So my solution is to put:
setpriority(activets, 10);
In the start of the breakto requirement, which will give any "broken task" (the first item on the ASRS and the second item off) a higher priority than any other TS's for that crane, thus ensuring my partial unloads don't happen any more.
It seems so simple now....
vBulletin® v3.8.7, Copyright ©2000-2012, vBulletin Solutions, Inc.