The AnyLogic 8.4 update comes with several important updates. One of them relates to the Material Handling Library. Now we have a new space markup element — the Crane. It allows you to simulate not just factory jib cranes, but also tower cranes like on construction sites, as well as robots that perform loading and unloading operations. This element can move objects around, including between unrelated conveyor networks, with the help of another new element — the MoveByCrane block.
Here, we will teach you how to use these new elements, using the example models: MoveByCrane and Jib Cranes at Press Shop. Get ready: this post is for those who are already familiar with the Material Handling Library and are confident using AnyLogic. If you have not worked with the new library, check out the previous tutorial posts on this topic:
- How to model conveyors
- How to simulate the operation of loaders and AGV’s
- How to simulate the processing of objects on a conveyor
All set? Then make sure that you have the latest version of AnyLogic installed, open the models and let’s go!
In this model, we can see a workshop process in action. The parts move along a conveyor to a crane which then moves them, first to a tank containing liquid and then to a processing machine. Finally, processed parts are put on another conveyor, which takes them away. This example shows:
- functionality of the MoveByCrane unit
- crane operation with agents associated with different markup elements
To get started with a crane, go to the Material Handling Library palette or Space Markup and drag a Crane markup element onto the canvas. Next, set the physical properties of the crane and its components: the trolley speed, the lifting speed, and also the jib rotation speed. In addition, the user can choose whether the crane will lift, rotate or move the load in the horizontal plane sequentially (step-by-step) or simultaneously (turning and lifting are performed at the same time). In our model, the values of these properties are set by default. You can choose how the crane looks in the Type property of the Appearance section: either as an industrial jib crane, or as a tower crane with a cat-head or flat top.
In the model, the tankNode node (the Rectangular Node type) and the machineNode node (the Point Node type) are located in the crane working area. The latter is the base location for the machineResource resource (ResourcePool type). Also, two conveyors serve the crane. Please note that in order to join a crane move queue, an agent and its destination must be within the working area of the crane.
The source block generates agents — parts for the production process. Immediately after creation, they are transported to the crane by the convey block (type Convey). Please note that in the Convey block, Leaving the conveyor on exit remains unchecked. As soon as the crane begins to move a part, the part is automatically removed from the conveyor, and the next part takes its place.
The block toTankByCrane (type moveByCrane) is responsible for moving parts from the conveyor to the tank. The tank is a node in the model so, in the Destination block property, the Node type is selected as the type, and the tankNode option is selected for the Node property. In the Crane property, the markup element - crane - is chosen, it will move the parts — the agents. For simplicity, in this case, the crane loading and unloading processes are instantaneous, so the properties of Loading Time and Unloading Time are left unchanged. The option Use operation time is not active, since we do not know the duration of each crane movement — it is automatically calculated based on the speeds specified for the markup element. If the duration is known, this option can be selected.
In our model, the order in which parts move between stations is important, so the Custom option is selected in the Agent selection pattern property. This allows you to sort the movement orders the crane receives. We will return to this option.
The crane carries parts over various objects when it is in operation. To prevent it from hitting anything, the Minimum safe height is set to 3.5. This is the height the parts will be raised by crane before moving. If you leave this value equal to zero, the crane will move parts at the same level they arrive.
After moving, the parts are kept in the tank using the inLiquid block (Delay type). They are then moved with a crane to the processing machine using the toMachineByCrane block (MoveByCrane type). The machine is described by a machineResource block (type ResourcePool) and is located in the machineNode node — the base location of the resource. To move a part to the processing machine, go to the ToMachineByCrane block and set the Destination is property to the Agent option and in the Agent property enter machineResource.iterator().next(); This code allows you to select any resource from the machineResource block. Since there is only one resource block — the processing station — it is chosen, and parts can now move to it by crane.
Next, parts are processed at the processing station in the processing block (type Service). But, before the crane can start to move a new part to the station, it must remove the previous part from it, otherwise the processing station will be occupied, and the crane transfer blocked. To do this, the model uses a simple rule — only one part can be on the crane or at the processing station at a time. To set this rule, the toMachineByCrane and processing blocks, in the process diagram, are enclosed in a restricted area. This limits the number of agents by using the raStart blocks (restrictedAreaStart type) and raEnd blocks (restrictedAreaEnd type) and setting the Capacity (max allowed) property to 1. These settings ensure the station is vacant before the crane starts moving a new part there.
The last block associated with the operation of the crane is toConveyorByCrane (type MoveByCrane). It moves parts from the processing station to the exit conveyor.
Parts can be put on the conveyor with a specified offset (set toConveyorByCrane block, Destination is = Conveyor to see the offset setting in the properties) or at a specific point on the conveyor (Destination is = Position on conveyor). We are using the second option. The crane will move finished parts to the conveyor and then the conveyToExit block (type Convey) moves them out of the workshop. Since the crane places parts on the conveyor, we can indicate the current position as the starting point in the Move to/from property.
We promised to come back to the order of the movement of parts between stations. In all three moveByCrane blocks, it is specified using the Agent selection pattern option. Since, in our model, all movement operations are performed by one crane and the processing areas have limited capacity, it is necessary to clearly define the sequence the crane performs simultaneous requests. In our example, the crane first removes parts, one at a time, from the processing station to the exit conveyor, then from the tank to the processing station, and finally, from the entry conveyor to the tank. This logic is captured using the MoveByCrane blocks Custom pattern properties: from the highest, in the toConveyorByCrane block (3), to the lowest, in the toTankByCrane block (1).
Jib Cranes at Press Shop Model
If you have read our previous tutorial posts on the Material Handling Library, then you will know that the transporter can pick up agents directly from conveyors. But what if a crane is involved in the unloading process? Let's look at the example of a simplified model of a machine press shop. In it, metal sheets pass along a conveyor through two processing stations and are then stamped to form the side panels of a car body. At the end of the conveyor, the crane removes them one by one and places them on the automated guided vehicles (AGV) that carry the panels to another workshop.
In the model, the first crane — loadingCrane — is located at the beginning of the conveyor, and the second — unloadingCrane — at the end.
First, we describe the processes of interaction between the cranes and the conveyor. Agents — metal sheets for processing — are created in the metalSheetSource block (type Source) and then added to the buffer (block type Queue) near the conveyor. After that, they are moved one by one to the conveyor using a crane in the loadByCrane block (type MoveByCrane). For this, a crane is defined in the block and used to perform the loading (the Crane property, loadingCrane value), in the Destination is property we use the Position on conveyor option. For Position on conveyor, choose loadingPoint.
After loading, the metal sheet begins to move along the conveyor in the convey block (type Convey) and passes through two processing stations — press, and cutMachine. When processing is complete, the agent.receive("processed") function is called in the action On process finished to change the agent to the next state in its state chart. In our case, a specific agent animation is attached to each state. This allows the output from the two stations to be animated.
As soon as the part reaches the end of the conveyor, it falls into the unloadByCrane block (type moveByCrane). The movement logic for the car panels is already prepared — we will explore how panels are moved to an AGV by crane a little later.
We now need to describe the AGV movement logic. They transport the finished panels in a trolley to the welding shop. This means, the trolley is an agent transported by an AGV. The group of AGVs is described by the agvs block (type TransporterFleet). In our model, there are two AGVs, so the Capacity property for the agvs block = 2. At the start of the model, they are located in the point nodes dropoffTrolleyLocation and pickUpTrolleyLocation.
There are always free carts in the model. They are created using the sourceTrolley.inject(1) function in the Pickup block when the previous trolley arrives at the panel loading point. The first trolley is created at the start of the model. They are generated by the sourceTrolley block (Source type) and placed in the pickupTrolleyLocation node (Point node type). In the toLoadPoint block (type MoveByTransporter), trolleys seize a free AGV, which then takes them to the conveyor. In order for an AGV to reach the end of the conveyor, the End of the conveyor option in the Offset from property of the toLoadPoint block is selected. Property Release transporter is not selected: this allows AGVs to stay with a trolley and wait for the loading process and the next transport command to finish.
The next block in the flowchart — toAssemble (type MoveByTransporter) — is responsible for transporting trolleys with panels to the welding shop using the same AGVs. Since an AGV is already connected to a trolley, the Seize transporter property is unchecked and the Destination is property is set as dropoffTrolleyLocation node (type Node). Having delivered a trolley to the specified point, an AGV will automatically be released and will start the carriage of the next trolley.
If you are building a model from scratch, it's time to put together the transport diagrams for the trolleys and metal sheets. This is done using the, already familiar, pickup block (type Pickup) between the toLoadPoint and toAssemble blocks: it is responsible for placing the panels in the trolley container. The number of panels being carried is determined using the numberOfBodyPartsToDeliver parameter in the Quantity property of this block. Note: In the Pickup field, the option Exact quantity (wait for) is selected. This will keep the trolley in place (in the pickup block) until the specified number of panels is loaded onto it.
Since the model uses several AGVs, you need to know which of them is currently receiving panels. Therefore, in the pickup block, in the action On enter, the arriving trolley is “remembered” in the variable loadedTrolley (code loadedTrolley = container).
In the unloadByCrane block, the desired AGV is indicated as the point to which the crane should transfer the agent: in the Destination is property, choose the option – Agent, and the Agent field which appears should be set to loadedTrolley. Note that the crane will try to move the agent to the destination as soon as it is taken from the conveyor. To stop the crane from starting to load before an AGV arrives, a waitForAGV block (Hold type) is placed in front of the unloadByCrane block (MoveByCrane type). It will let through the number of panels needed to load one trolley, after which it will stop the flow of panels/agents. The Mode property Block automatically after N agents (use unblock()), with the number of agents passed in the property N agents for self-block, is responsible for this. As soon as a new trolley is ready for loading in the pickup block, the flow of agents/panels arriving at the crane is unblocked by calling waitForAGV.unblock(); in the pickup action property On enter.
Now you know how to simulate cranes in AnyLogic and integrate them into production processes. The main things to remember:
- All points where agents may queue for a crane move, and also the agent destinations, must be located in the crane's working area.
- If you need to load an agent onto a conveyor using a crane, make sure that the transporter is in the working area of the crane.
- When setting up a MoveByCrane block, remember to specify the minimum safe height to which the crane must lift the load. If you leave this value equal to zero, the crane will move the workpiece at its current level and can pass through/hit objects on the way.
- If the crane needs to specify the sequence of moving requests, use the Agent selection pattern property in the MoveByCrane block.
What else would you like to learn from our how-to articles? Tell us in the comments below, and don't miss the new articles when they come out — subscribe to our monthly newsletter.