Table of Contents

Table of Contents

Key Concepts About Warehousing

Key Concepts About Warehousing

What are FlexSim's Warehousing Tools?

FlexSim has robust set of tools for modeling warehousing facilities. These warehousing tools will help you analyze the many aspects that go into complex warehouse and storage design. With these tools you can create realistic multifaceted models for data analysis.

Before creating a complex warehousing model however, it’s recommended that you simplify the model concept as much as possible early on. Warehousing models have many dimensions that can get very complicated very quickly. The first recommended step therefore, is to determine the question and specific data that you are trying to gather from your model.

It is valuable to begin a warehouse simulation with a specific question because this will give your model direction in your design. Eliminate any details from the modeling process that don’t help to answer this question. If an element is not critical to examining the question you’re trying to answer, then you can save yourself extra work by abstracting and making educated assumptions about those elements.

Some examples of incomplete or difficult questions might be:

  • How do I optimize my throughput?
  • How do I improve my order turnaround time?

These questions are too open-ended and vague. They don’t define enough measures to determine what’s “optimal.” These types of questions often lead to overly complicated models that are challenging to parse through, because any element could potentially affect these vague measures.

A good question, however, will include both a proposed change and a performance measure to compare against. Some examples of good questions to ask include:

  • Will this proposed racking system be able to handle the picking throughput I need?
  • Which of these two layouts renders the lowest turn-around time from order to shipment?
  • Do we have enough racking in our facility to handle projected inventory levels?

What is most important to determine, is to figure out what data you need to extract from your model. Once you’ve determined the data that you need from your model, there are several areas of consideration about building a warehouse model: Laying out your warehouse, monitoring inventory, and retrieving product.

For more detailed advice and information, please refer to the article detailing concepts of Project Goals and Scope.

Laying Out Your Warehouse

When designing a warehouse simulation, one of the key elements to determine is the layout of the warehouse itself. How and where are items going to be stored? Where do operators and transports need to be able to access? How are items going to be addressed and zoned?

The Storage System

Whenever you drag out a rack object into a model for the first time, you will notice that FlexSim will create a new object in your Tools folder. If you click on the Toolbox tab on the left panel of the screen, you can find the Storage System object listed there. This Storage System centralizes the logic of your racking and warehousing objects into a single hub. Labels, rack visualization, addressing schemes, and triggers can all be created and controlled from the Storage System object. This document will reference the Storage System tool in the sections below, but for a full complete reference to the Storage System and its features please refer to the Storage System Documentation.

Bays, Levels, and Slots and the Dimensions Tab

The organization of racks is setup in a matrix style grid or table made up of bays, levels, and slots. If you double-click on a rack object in the 3D view, you can open its properties window. There you will see a tab labeled Dimensions. Click on that tab, and you will see the following table. (It might have some alterations based on which type of rack you clicked on, but the same basic system works across all rack types.)

In this view you can see how the bays, levels and slots of a rack are organized. Bays represent the areas along the horizontal axis, levels are the spaces along the vertical axis, and slots refers to further divisions of space within each bay and level “cell.”

In this window there are fields that allow you to edit the number of Bays and Bay Width, the number of Levels and Level Height, and the number of Slots and Slot width for the rack object. You are also able to click on, or click and drag, within the visual grid map of the rack in this window, to highlight and select individual slots, or groups of slots. (IF you click in the white space around the grid map, then by default all slots will be considered selected.) Once selected you can check or uncheck the Storable Slots checkbox to deactivate those selected slots as storable. When unchecked, you will notice that a red X marks the visual map for those slots, and in the 3D view, the shelves for those slots disappears. This means that no items will be able to occupy that slot. This can be used to create racks and storage spaces with irregular or non-uniform storage locations and shelves.

Bay and Level Progression

The Pick-Face of a rack is the side of the rack that Operators and Transports will load items from. In a typical warehousing environment this is where Pickers retrieve items from a rack’s shelves, which is where the term “pick-face” comes from, it’s the face of the rack that is picked from. You can consider the pick-face of a rack to be the “front” side of the rack for logical purposes. In the Dimensions tab of a rack’s properties window, the grid map is a visual reference of the rack as if you were looking straight onto the pick-face of that rack. There you can see how bays and levels are counted. In the default settings, the bay’s count progresses, starting at 1, from left to right, one bay at a time. Levels are counted the same, starting from bottom up to the top. This count is what is referred to as Bay/Level Progression, and the count is what is referred to as Bay Stride.

In the properties window of the rack, you can click on the first tab again, labeled Storage Object. Here you will see several options for determining Bay Progression, Bay Stride, and logic and visual options for items being placed in the rack.

In the Address Mapping section, we can change how our rack will count its Bay and Levels. The first menu in this section, labeled Addressing Scheme allows you to refer to an Address Scheme created in the Storage System object mentioned previously. This document will go further into Address Schemes in the Assigning Locations section of this document.

The next set of fields allows you to change how Bays and Levels are counted in the rack. The Start fields will determine which number the first bay, level, or slot will begin on numerically. The Stride fields will determine how the bays, levels, or slots are counted from there. Finally, the Progression menus will let you determine which direction the bay, level, or slot progression will go. By default, the Bay Progression is X+, meaning that bays will count progressing along the X dimension of the object in a positive direction. (Or from left to right along the pick-face.) If you select the X- option, then the bays would progress in the opposite, from right to left, along the pick-face. Bay and Slot Progression will be determined along the X dimension, Level Progression is along the Z dimension of the rack, or up and down along the pick-face. Z+ is counted from bottom to the top, and Z- will start the count at the top and progress towards the bottom.

One example of an alternate way of setting the Bay Progression would be if you had two racks with their pick-face facing the center of an aisle, and you wanted to create a Bay Progression that would alternate along the length of the aisle. One side of the aisle could progress with the odd numbers counting up, while the other side would be the even number counting in the mirrored or opposite direction.

Assigning and Finding Locations and Items

Once you’ve determined the layout of your warehouse, the next step is to determine how you are going to assign locations to the items stored in the warehouse. There are multiple ways to do this. If you have an Order Table, or some kind of inventory spreadsheet that contains address information for product, you can set up an Addressing Scheme in Storage System properties window. Alternatively you can use some of the Storage.system commands to create rules or queries to determine the slot for an item.

Addressing Schemes

If you already have a table of inventory data with SKUs and address information (such as an Order Table, or an In-Bound Table for arrivals) then you can implement an Address Scheme from your Storage System tool in the toolbox. If you haven’t done so already, you can drag out any rack object into the model, to initialize the Storage System object in the toolbox. Once a rack is created in a model, the Storage System object will automatically be initialized in a model. You can open the Storage Systems properties window, by selecting the Toolbox tab, and double clicking on the Storage System listed in your tools. Once open, you can select the Address Schemes tab to bring up the information and details for creating Address Schemes.

Here in the Address Schemes tab you will find multiple fields to help create and maintain multiple Addressing Schemes for your project. The top field displays the currently selected theme, and next to the field are multiple buttons for creating, copying, deleting, and reordering the Address Schemes. There is no limit to the number of different Address Schemes a model can have.

The next field line has an Example of how your selected address scheme is written. Before you begin to define your own address scheme, it is important to understand the elements that make up the different parts of an address. From the largest grouping to the smallest, addresses are made up of Zones, Aisles, Bays, Levels, and Slots. Zones represent the largest categorization of location in the warehouse, usually meant to refer to an area in the warehouse that includes a group of racks. Aisle refers to the aisle that a group of racks could belong to. Bay refers to the bay in the rack, followed by Level. And Slot is the specific location that an item is going to be assigned to. You should notice that with the default scheme selected, the Example field will read as Z-A-1-1-1. This string of characters provides you with a sample of what an address String for this Address Scheme will look like. In this case the first character represents the Zone. Then a dash, followed by the second character representing the Aisle. Then further dashes separating the Bay, followed by the Level, and then finally the Slot. When searching for a location Slot by address, this string is an example of what will be passed into the search parameter.

Next to the Example field you will see a green “+” button that will allow you to create a new character definition for the Address Scheme. Below the Example, you can see the entries for character definitions for your current selected scheme.

Each entry below the Example field have fields for defining a character ID in an Address scheme. The first field defines which element of the address is being identified. The menu field next to the ID field, will determine what type of character the address will expect for this element, either number or letter, or arbitrary (meaning it could be either). The Fixed Length checkbox and following field will define whether there is a set number of characters in an Address defining that element, and how many characters are required. Then the Filler field will determine what character can act as a “filler” if the number of characters is too few. Finally, you will notice that there are some entries with just a single field. These entries and fields are to define what characters will act as a spacer between the two Character IDs.

Once you’ve either created or selected an Address Scheme, you can now assign Racks to be included in that scheme. You can double-click on a Rack object to open its properties window, and in the Storage Object tab, under the Address Mapping section, you can select your Address Scheme from the corresponding dropdown menu. Once a scheme is selected, you can assign a Zone or Aisle ID.

Objects Tab

You can also get an overview of every Rack Object connected to the Storage System by clicking on the Objects tab of the Storage System’s properties window. Here you can see and reorder any of the Racks and edit their Zone or Aisle IDs. You can also edit Start, Stride and Progression of Bays, Levels, and Slots. By default, only Bays are visible. However, at the top of this window there’s an options button, witch checkboxes that will allow you to show or hide which fields for your Rack objects that you’d like to edit.

Getting Slots Using Addresses

Once you have an addressing scheme set up, there are some simple FlexScript commands that you can use, to get a slot and assign it to an item.

FlexSim has a Storage class used in FlexScript commands that deal with any of the Storage Objects and Warehousing tools. To learn more in depth about the Storage.system class and its functions and attributes, you can look at the Storage.System FlexScript API.

Using the Storage.system.getslot() function we can get a Slot based upon the address we pass in. The Function expects a string, and it will match the characters of the string against any Address Scheme that has been set up in the model. If the address matches the scheme, it will locate that slot, and return that slot. From there the slot can be assigned to the item. The following script is an example of how you might get a Slot and assign it to an item.

Storage.Slot slot = Storage.system.getSlot("1-A-1-3-2");
if (slot && slot.hasSpace(item)) {
    Storage.Item storageItem = Storage.Item(item);
    storageItem.assignedSlot = slot;
}
token.Slot = slot;
        

In this script we create a “slot” variable of the System.Slot class. We assigned it a value by using the Storage.system.getSlot() function, and passed in a string that matches an Address Scheme in our system. The function will then find that slot based on the address and return it as a value.

The next lines of code then ask if a slot was retrieved, and if it has space for our item using the slot.hasSpace() function. If so, the slot is assigned to the item. Assigning slots to items is a crucial step, because once the item has a slot assigned to it, if the item is then moved to the rack containing that slot, the item will be placed automatically into the corresponding assigned slot.

Setting Up Labels on Slots

Another way of assigning slots and slot values, is to use labels. In the Storage System object’s properties, you can click on the first tab named Slot Labels. This window will be blank by default, but by clicking on the green “+” sign you can add a label for all the slots in your Storage System. This would be a good way to attach a Type label to the slots, for example. Once a new label is created here, you will notice several fields that give you options for the newly created label. The first field is name of the label, then you can select a color palette from your selection of Color Palettes in your model (See the Color Palette reference documentation for more information.) The Indexed checkbox will allow you to select whether the label is indexed or not. (See more information about Indexing here.) Finally, the last field will let you determine if the label has a default value.

Finding and Assigning Slots from Labels

If your racks and storage system are set up with labels, you can use one of the functions of the Storage class to now search for a Slot to assign to your item. Much like the ability to get a slot and assign it using the address system. The Storage class also has a function to find a slot through a query of the labels instead. Using SQL syntax, you can pass a query as a string into the Storage.system.findSlot() function to return a slot you can then assign to your item

Storage.Slot slot = Storage.system.findSlot("WHERE Type = $1.Type AND slot.hasSpace($1) ORDER BY RAND()", 0, item);
if (slot) {
    Storage.Item storageItem = Storage.Item(token.Item);
    storageItem.assignedSlot = slot;
}
token.Slot = slot;
        

In this script, we first created a variable “slot” to act as the slot we are trying to get. We assign it a value, by using the Storage.system.findSlot() function, and passing in a query. The first parameter in the function is a string of the query. In this query, we are asking the Storage System to find a slot where the Type label of the slot matches the Type label on the item, and to check if the slot has space for the item, then to randomly order any matching slots as the returned slot or slots. The next parameter in the function is a 0, this is a reserved parameter for FlexScript, and must be 0. Finally, the last parameter is the value that will be represented by $1 in the query, and every optional parameter after would be further represented by $2, $3, $4, etc.

The next lines of the code ask if a slot was returned by the function, and if so, to assign the retrieved slot to item that is going to be stored.

Once an item has a slot assigned to it and is moved into the Rack containing that slot, the rack object will recognize the assigned slot and place the item there.

Finding and Retrieving Items

Just as you can use the Storage.system.findslot() function to find slots and assign them to items, you can also search the Storage System for items using Storage.system.findItem(). The parameter of the function expects a string query just as the function for finding slots does, but it will return a reference an item instead of a slot. Using this function will allow you to get a reference to an item, which you can execute logic for retrieval. Here is an example script using the Storage.system.finditem() function.


Storage.Slot.Item slotItem = Storage.system.findItem("WHERE Type = $1 ORDER BY RAND()", 0, token.Type);
token.Item = 0;
if (slotItem) {
    slotItem.storageItem.assignedSlot = 0;
    token.Item = slotItem.item;
}
        

In this example code, we are creating a variable called “slotItem” which is a Storage.Slot.Item class of object. This object has some unique attributes and functions associated with it. In the script we run a query through the Storage.system.findItem() function, which will return a Slot Item.

The next lines of code then assess whether a Slot Item was returned, and if so, to then assign the associated Slot Item to an Item label on a token. From here we now have a reference to the found item through that Item label and can execute logic to retrieve the item or any other logic we want to apply.