Jordan Johnson avatar image
Jordan Johnson posted Phil BoBo edited

2019 Update 2 Warehouse Demo

This is a demo model for the new warehouse functionality found in version 2019 Update 2:


The basic premise of this model is that items of a particular type come in, and must be placed in slots for that type. Orders also come in, requiring items of a particular type, that must be retrieved from storage.

The model is meant to be a general concept model. It demonstrates the use of many of the new features in 19.2, and embodies some high-level "how-to's" of warehousing that are discussed in the user manual. Most logic for the model is implemented in a process flow. The process flow logic is separated into three main categories, namely initial inventory, inbound, and outbound processes. Further, the outbound process demonstrates both random-based order generation as well as history-based order generation.

Initial Inventory

The model includes a Global Table of Initial Inventory. The process flow's initial inventory section reads this table, and then creates items and places them into slots based on that initial inventory. This logic relies on the Address Scheme defined in the Storage System object, and uses direct addressing to get a slot using Storage.system.getSlot().


I use the process flow to assign a slot to each incoming item. I use an Assign Labels activity called Find Slot to do this. This uses a pick list option that wraps a call to Storage.system.findSlot(). The query matches the Type of the item with the Type of the slot, and also ensures that the target slot has space to fit the incoming item. The query also randomizes the order. Randomizing the order would likely not be necessary in most situations, but it makes the demo look nice.

If the Find Slot activity properly finds a slot to store the item, then I go ahead and assign the the item to that slot, and have an operator place it in the rack.


I also use the process flow to generate orders, and to reserve items in the storage system for those orders. In most warehouse simulations, order generation can be driven in two ways. First, you can use random probability distributions to generate orders based on general throughput metrics. Second, order generation can be based on historical data.

This model gives an example of each method. In the random method, orders are generated randomly every ~30 seconds. Each order includes a number of SKU line items (again, random) and each line item includes a quantity of that SKU (again, random). Order tokens spawn line item tokens, which in turn spawn tokens associated with individual picks (the Fill Out Individual Picks process). For each pick, the token finds an item in storage that matches the target SKU. This is an Assign Labels activity (Find Item by SKU) with a pick option that wraps a call to Storage.system.findItem(). It finds an item that matches the required type, again using a query. Once the item is found, it makes reserves the item as "outbound" by assigning the Storage.Item.assignedSlot property to null (Set to Outbound activity). This ensures that no other process will find that same item for picking.

The history-based order generation process uses much of the same functionality as the random-based, but it instead reads an "OrderHistory" table to determine when orders are started and what those orders contain. The OrderHistory table represents a simplified format for what you would likely see in a standard orders table. First, the process flow creates a transformed table that aggregates each order into a single row (this could technically be done as post-import code, but I do it in the process flow for visibility). Then the process flow loops through that transformed table, waiting for the start time of each order, then spawning that order.

Custom Rack Visualization

I have also customized the visualization of the racks. I have added a text to the front (and bottom on the floor) of a rack slot that will show the address of that slot. Further I've given the text a background that is color-coded to the SKU that that slot is designated to store. This was all done through the Storage System's Visualizations tab. I customized the Rack visualization.

· 18
5 |100000 characters needed characters left characters exceeded

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.


I have a question in regards to the SKU. It seems to me that SKU is pre-assigned to slot on the racks, since during "InBound" the incoming flowitem does a "findslot" by match its SKU to storage SKU. How is the SKU being assigned (in the model)?

1 Like 1 ·

I think I found the answer... the SKU is painted onto the Racks slots using the "Paint Slot Labels". :)

0 Likes 0 ·

@jordan.johnson Thanks for this. I think the warehouse function will be useful in some upcoming projects. I have two questions, or really more one observation and one question.

The observation is that in a sense the warehouse object is somewhat like a list, with the slot labels being somewhat like custom fields in a list.

The question on the model is -- where does the SKU get assigned to the slot? I followed through the initial inventory logic, and the items certainly have SKUs, but I don't see where they are assigned, either to the item or to the slot. I'm guessing it's on the Slot Label tab, but if so I definitely don't understand how.



1 Like 1 ·

I assigned the SKU to slots using the Slot Painter tool, in the library. If you click on it, you can use Quick Properties to set which label you want to see. Then you can see the value of the label on each slot.

1 Like 1 ·

How can I have the operator pick me up several orders at the same time depending on the order history?

I want to know if the operator can retrieve the first order at the same time, is to say that the order of 5 boxes of Cola 350ml Can 24 Pack collect them at the same time.

1 Like 1 ·
captura-li.jpg (741.7 KiB)


For me the rack addresses are not drawn correctly, but as black boxes, when I open the demo model. See the attached image. Is this a graphics issue or something else?

Thank you!

Kind regards,


0 Likes 0 ·

Change your OpenGL Context from "Core Profile (3.3)" to "Recommended":

In 19.2, the Rack's text rendering is using a deprecated OpenGL texture format, so it doesn't render correctly with a Core Profile.

While making improvements to the text rendering for 20.0, we've fixed this bug. For now, just use a Recommended context instead of a Core Profile.

1 Like 1 ·
opengl-context.png (15.0 KiB)

Hi @phil.bobo

It works! Thank you.

Kind regards,


0 Likes 0 ·


The model throws exceptions into the system console after roughtly 12000 seconds and there are more than one pallet in a single staging area. Possibly due to the randomness (even though I set "repeat random streams") the exceptions happen at different times so I could not catch the error.

Could you look to what happens and explain what needs to be done to fix it?

Thank you!

Kind regards,

0 Likes 0 ·

The repeatability issue is because the "Order Picking" section of the Process Flow has an Unload task where the Station is a flowitem. That flowitem's precise location will depend on when the screen was last repainted. To fix this, you can add an updatelocations() call before the activity:

(Alternatively, you could change all the StagingArea queues' Item Placement setting from Stack Inside Queue to Do Nothing. Then the queues wouldn't be setting the pallets' locations and need to be updated.)


1 Like 1 ·

The "Fill Out Individual Picks" section of the Process Flow isn't handling the situation where an order wants an item but no items of that SKU are available. In a real model, you should use a Decide activity in order to handle that situation:


0 Likes 0 ·
Show more comments



anthony.johnson contributed to this article jordan.johnson contributed to this article

Related Articles