Pallet Rack


The space markup element Pallet Rack graphically defines the pallet rack used in warehouses and storage zones.

Pallet rack may have one of these three configurations:

  1. One aisle, one pallet rack
  2. Two aisles, one pallet rack
  3. One aisle, two pallet racks

The figures below illustrate all three cases:

To create complex rack systems, use several pallet rack shapes, then add RackSystem block of the Process Modeling library and configure it.

It creates a set of nodes and segments along given aisle, and manages the agents stored in the locations on both sides of the aisle, possibly on different levels.

The parameter Positions (per row) defines how many network nodes will be created on each side of the aisle; each node is actually a footprint of a number of vertically located cells (controlled by Number of levels parameter). Therefore, a storage with 60 positions and 4 levels will have 60 * 4 * 2 = 480 cells, 2 means the two rows on each side of the aisle. Each cell has three coordinates: row (0..1), position (0..npositions), and level (0..nlevels).

A network path goes through the center axis of the aisle to the back entry node. In between each pair of the opposite cell nodes Pallet Rack creates a short path across the aisle and a small node in the center of the aisle so that all cell nodes are connected to the network.

The width of the cell footprint nodes (i.e. their dimension along the row) is calculated automatically as the length of the aisle divided by the number of positions per row. The depth of the cell is specified by the user in the corresponding parameter. The cell node depth, the topology of the aisles and the network elements drawn by the user have to be consistent, e.g. there should not be node intersections. 

These are the main operations on a cell supported by Pallet Rack:

Pallet Rack also exposes a number of functions to obtain its state: capacity, the number of occupied, reserved and free cells, utilization statistics, etc. You can search for an agent in the storage, locate the free cell closest to either of the aisle ends, find out what network node corresponds to a cell, and so on. As long as you have access to the node rectangles, you may use colors to indicate the cell states: reserved, occupied, free.

The normal scenario for an agent that needs to be stored is the following:

  1. Find out the free cell
  2. Reserve that cell
  3. Move the agent to the cell node, possibly with the help of some resources
  4. Put the agent there

Please note that Pallet Rack does not remember which agent has reserved a cell, so it is the user’s responsibility to make sure the cell is later used by the correct agent.

Then, for an agent that needs to be taken out of the storage the scenario is this:

  1. Find out the cell where the agent is stored and its network node
  2. Maybe, call resources to the node
  3. Remove the agent out of the cell
  4. Move the agent to the destination node

The simplest way is to use the two objects RackStore and RackPick specially designed to support the most frequent operation on storages.

Pallet Rack has four extension points where the user can specify actions that will be performed when an agent is put or removed from the cell, and also when a cell is reserved or released.

In case there is a number of uniform storages that are used in a similar way, it makes sense to have a central access and management point for them. The Rack System object is specifically designed for that purpose.

But you can specify to what cell the pallet should be put. Each cell has three coordinates: row (0..1), position (0..npositions), and level (0..nlevels). So you can iterate through all levels and positions.

 To add a pallet rack

  1. Drag the  Pallet Rack element from the  Space Markup palette into the graphical editor.
  1. Connect the pallet rack to the network (a network path should go exactly through the center line of the aisle). Workers and forklift trucks will use this path to get to the pallet rack cells.

  2. Configure the pallet rack in its properties: set the rack's TypeOne rack, one aisle; One rack, two aisles; or Two racks, one aisle.
  3. Set the Number of levels, Number of deep positions, Number of cells.
  4. Open the Position and size section of the properties, and set the Length, Pallet rack depth, Aisle width.
  5. Having finished configuring the structure of the pallet rack, check that the pallet rack is still connected to the network. Select the pallet rack in the graphical editor. If the pallet rack is correctly connected, its aisle will be highlighted in green on the rack selection. If not, drag the rack shape on the path so that the path goes exactly along the aisle center line.

Properties

General

Name – The name of the rack. The name is used to identify and access the rack from code.

Ignore – If selected, the rack is excluded from the model.

Visible on upper level – If selected, the rack is also visible on the upper level where this agent lives.

Lock – If selected, the rack shape is locked. Locked shapes do not react to mouse clicks - it is impossible to select them in the graphical editor until you unlock them. It is frequently needed when you use your shape as a background image for your animation and you want to prevent editing this shape while drawing other shapes over it.

Visible – Here you specify whether the shape is visible on animation at model runtime, or not. Using the control, choose yes or no.

Type – A combination of aisles and pallet racks: One rack, one aisle; One rack, two aisles; Two racks, one aisle.

Number of cells is – Choose if the number of cells should be Defined explicitly or Calculated based on the cell width.

Number of cells – [Available, if Number of cells is: Defined explicitly] The number of cells per row located on one level.

Cell width – [Available, if Number of cells is: Calculated based on the cell width] The fixed cell width.

Number of deep positions – The number of positions in the depth of each cell.

Number of levels – The number of (vertical) levels of the rack. 

Level height – The height of (vertical) levels of the rack. 

Appearance

Fill color – Rack cells fill color. 

Line color – Rack outline color.

Draw upright posts in 3D – Deselect this option if you do not need to draw upright posts in 3D. Then only "shelves" will be drawn. 

Cells between posts – Here you can type the number of cells between posts if the posts are drawn in 3D. It does not affect the 2D animation of pallet rack.

Position and size

X – X-coordinate of the rack (namely, its far left corner).

Y – Y-coordinate of the rack (namely, its far left corner).

Z – [Enabled if Show in 3D option is selected] Z-coordinate of the area, in meters. The value is relative to the Z-coordinate of the area's ground. 

Length – The length of the rack.

Pallet rack depth – The depth of the rack.

Aisle width – The width of the rack aisle(s).

Rotation – Rack's rotation angle in XY plane. 

Advanced

Show in - Here you can choose whether you want the rack shape to be shown both In 2D and 3D animation, or in 2D only, or in 3D only.

Show name – If selected, the shape's name is displayed on the graphical diagram.

Functions

Structure

PalletRackType getType() - Returns the type of this pallet rack.

setType(PalletRackType type) - Sets the type of this pallet rack.
Parameter: type - the type of this pallet rack.

double getCellWidth()  - Returns the width of cell.

setCellWidth(double cellWidth) - Sets the width of cell.
Parameter: cellWidth - the width of cell.

double getDepth() - Returns the depth of the pallet rack.

double getDepthRight()Returns the depth of the right pallet rack.

setDepth(double depth) - Sets the depth of the pallet rack.
Parameter: depth - the depth of the pallet rack.

setDepthRight(double depthR) - Sets the depth of the right pallet rack.
Parameter: depthR -  the depth of the right pallet rack.

double getAisleDepth() - Returns the depth of the aisle.

double getAisleRightDepth() - Returns the depth of the right aisle.

setAisleDepth(double aisleDepth) - Sets the depth of the aisle.
Parameter:
aisleDepth - the depth of the aisle
          
setAisleRightDepth(double aisleRDepth) - Sets the depth of the right aisle.
Parameter:
aisleRDepth - the depth of the right aisle.

double getLength() - Returns the length of the pallet rack.
          
double getLevelHeight() - Returns the height of the level.

          
setLength(double length) - Sets the length of the
pallet rack.
Parameter: length - the length of the pallet rack.
          
setLevelHeight(double levelHeight) - Sets the height of the
level.
Parameter: levelHeight - the height of the level.

int numberOfDeepPositions() - Returns the number of positions in the depth of each cell.

setNumberOfDeepPositions(int nDeep) - Sets the number of positions in the depth of each cell.
Parameter:
nDeep - the number of positions in the depth of each cell.

int numberOfLevels() - Returns the number of levels in this pallet rack.

setNumberOfLevels(int nLevels) - Sets the number of levels in this pallet rack.
Parameter: nLevels - the number of levels in this pallet rack.

int numberOfPositions() - Returns the number of positions (cells) in one shelf. The total number of positions may be calculated by multiplying this number by number of deep positions and by number of levels and by two, if this object contains two pallet racks.

void setNumberOfPositions(int nPositions) - Sets the number of positions (cells) in one shelf.
Parameter: nPositions - the number of cells in one shelf.

int numberOfRows() - Returns the number of rows (pallet racks), 1 or 2.

Placing / picking agents into / from the pallet rack

boolean hasSpace() - Tests if the storage has free space, i.e. if there are cells that are neither occupied nor reserved. Returns true if there is enough space for at least one more agent.

boolean isFree(int row, int position, int level)Tests if a given cell [row,position,level] is free, i.e. neither occupied nor reserved.
Parameters:
row - the row (0, 1, ..)
position - the position in row (0, 1, ..)
level - the level (0 is the lowest)
Returns: true if free

int nFree(int row, int position, int level) - Tests if a given cell [row,position,level] is free, i.e. neither occupied nor reserved and returns the number of free slots in the depth of the cell.
Parameters:
row - the row (0, 1, ..)
position - the position in row (0, 1, ..)
level - the level (0 is the lowest)
Returns: the number of free slots in the depth of the cell

reserve(int row, int position, int level, boolean leftAisle)Marks a given cell [row,position,level] as reserved. The cell must be free.
Parameters:
row - the row (0, 1, ..)
position - the position in row (0, 1, ..)
level - the level (0 is the lowest)
leftAisle - [for 2-aisle pallet racks]: from which aisle the cell reserve should be placed

int reserved() - Returns the number of reserved cells in the pallet rack(s).

int nReserved(int row, int position, int level)  - Tests if a given cell [row,position,level] is reserved.
Parameters:
row - the row (0, 1, ..)
position - the position in row (0, 1, ..)
level - the level (0 is the lowest)
Returns: the number of reserved locations (may be > 1 for pallet racks with depth)

release(int row, int position, int level, boolean leftAisle)Discards a reservation of a given cell [row,position,level]. The cell must be reserved.
Parameters:
row - the row (0, 1, ..)
position - the position in row (0, 1, ..)
level - the level (0 is the lowest)
leftAisle - [for 2-aisle pallet racks]: from which aisle the cell reserve should be released

put(int row, int position, int level, boolean leftAisle, Agent agent)Puts the agent into the cell with the specified coordinates [row,position,level]. If the cell is occupied, signals error. Does not check if the cell is reserved.
Parameters:
row - the row (0, 1, ..)
position - the position in row (0, 1, ..)
level - the level (0 is the lowest)
leftAisle - [for 2-aisle pallet racks]: from which aisle the agent should be put to the cell: from the left or from the right one
agent - the agent

Agent get(int row, int position, int level, int deepPosition)Returns the agent stored at the specified cell [row,position,level], or null if the cell is reserved or free.
Parameters:
row - the row (0, 1, ..)
position - the position in row (0, 1, ..)
level - the level (0 is the lowest)
deepPosition - [if cells have depth] the index (0, 1, ..), counted from the aisle (or from the left aisle, if there are several aisles near this row)

PalletRackLocation getCellOf(Agent agent)Returns the coordinates of a cell with a given agent [row,position,level], or null if the agent is not stored here.
Parameter: agent - the agent

PalletRackLocation getFreeCell(boolean infront)Returns the array [row,position,level] with the coordinates of a free cell that is closest to either front or back of the storage, depending on the parameter infront. If the storage is full, returns null.
Parameter: infront - if true, the returned object will have the smallest available position

Agent randomEntity()Returns a random agent in the storage, or null if the storage is empty.

Agent remove(Agent agent) - Removes a given agent from the rack system and returns it. If the agent is not stored here, returns null.
Parameter: agent - the agent to remove

Agent removeFromCell(int row, int position, int level, boolean leftAisle)Removes the agent stored in a given cell [row,position,level] from the rack system and returns it.
Parameters:
row - the row (0, 1, ..)
position - the position in row (0, 1, ..)
level - the level (0 is the lowest)
leftAisle - [for 2-aisle pallet racks]: from which aisle the agent should be removed: from the left or from the right one

Agent removeFromCell(PalletRackLocation location, boolean leftAisle) - Removes the agent stored in a given cell [row,position,level] from the rack system and returns it.
Parameters:
location - the [row,position,level]
leftAisle - [for 2-aisle pallet racks]: from which aisle the agent should be removed: from the left or from the right one

Agent getByIndex(int index)- Returns the stored agent with a given index. The order of agents is internal and may change when agents are added or removed. If the index is greater than (number of agents - 1), returns null.
Parameter: index - the index

int capacity() - Returns the total number of cell positions (all the levels and all racks, if there are two racks), which is (1 or 2) * number of positions along row * number of deep positions * number of levels.

boolean contains(Agent agent) - Returns true if the given agent is contained within this object.
Parameter: agent - the agent

int size() - Returns the current number of agents in the storage.

resetStats() - Resets the statistics collected for this object.

Specific

double getNearestPoint(double x, double y, double z, Point output) - Calculates (using the output object) the point in this space markup element nearest to the given (x, y, z) point. Returns the square of distance to the point.
Parameters:
x
- x coordinate of the point
y - y coordinate of the point
z - z coordinate of the point
output - the output point to write result to.

double getNearestPoint(double x, double y, Point output) - Calculates (using the output object) the point in this space markup element nearest to the given (x, y) point. Returns the square of distance to the point (in the XY-projection). All the calculations are performed in the horizontal projection (z-coordinates aren't used, as if all of the z coordinates were zero).
Parameters:

x
- x coordinate of the point
y - y coordinate of the point
output - the output point to write result to. Note that output.z is left unchanged.

Position getPositionAtCell(int row, int position, int level, int deepPosition, double offset, double depth, boolean leftAisle, Position out) - Returns the position at the given cell.
Parameters:
row - the number of pallet rack (0 or 1). Used in two-row pallet racks (0 = left row, 1 = right row). If there is only one pallet rack, this should be 0.
position - position in row (0, 1, ...)
level - level (0, 1, ...)
offset - offset along row edge
depth - in-cell depth (perpendicular to row edge)
out - the Position object to write to (may be null)

deepPosition - [if cells have depth] the index (0, 1, ..), counted from the aisle (or from the left aisle, if there are several aisles near this row)
leftAisle - [for 2-aisle pallet racks, needed for orientation calculation]: where the face of agent should be oriented: as it was put from the left aisle or from the right one
Returns: the given output object (if was not null) or new Position with coordinates and rotations set.

Position getPositionAtCellEntry(int row, int position, int level, boolean leftAisle, Position out) - Returns the position at the given cell.
Parameters:
row - the number of pallet rack (0 or 1). Used in two-row pallet racks (0 = left row, 1 = right row). If there is only one pallet rack, this should be 0.
position - position in row (0, 1, ...)
level - level (0, 1, ...)
offset - offset along row edge
depth - in-cell depth (perpendicular to row edge)
out - the Position object to write to (may be null)
Returns: the given output object (if was not null) or new Position with coordinates and rotations set.

Position getPositionInAisle(int row, int position, boolean leftAisle, Position out) - Returns the position in the given aisle at the given cell.
Parameters:
row - the number of pallet rack (0 or 1). Used in two-row pallet racks (0 = left row, 1 = right row). If there is only one pallet rack, this should be 0.
position - position in row (0, 1, ...)
out - the Position object to write to (may be null)
leftAisle - [for 2-aisle pallet racks, needed for orientation calculation]: where the face of agent should be oriented: as it was put from the left aisle or from the right one
Returns: the given output object (if was not null) or new Position with coordinates and rotations set.

double getRotation() - Returns the rotation of the pallet rack in radians, clockwise.

setRotation(double rotation) - Sets the rotation of the pallet rack.
Parameter: rotation - the rotation of the pallet rack in radians, clockwise.