This example shows how to create a custom block with multiple storages and manage storage behavior using discrete-event System object™ methods.
Suppose that you manage a facility that produces items for customer orders. To prepare for repetitive orders, the facility produces a supply of items before the orders arrive. When a new order arrives, the stocks are checked for availability.
If the item is found in the storage, it departs the facility to fulfill the order.
If the item is not found in the storage, a new item is produced and the generated item departs the facility to fulfill the order.
To generate this custom behavior, you manipulate multiple storages through a
discrete-event System object, created using the matlab.DiscreteEventSystem
methods. To
observe the behavior of the custom block, see CustomEntityStorageBlockWithTwoStoragesExample
.
Generate a custom entity storage block with two inputs, one output, and two storage elements.
The desired behavior of the custom block is to select and output entities based on a reference entity.
Input port 1
accepts entities with type
Item
to storage 1
.
Input port 2
accepts reference entities with type
Order
to storage 2
.
When a reference Order
arrives at storage
2
, its attribute data is recorded as the reference
value, and the entity is destroyed.
The Order
arrival invokes an iteration event at storage
1
to search for an Item
carrying
data that is equal to the reference value.
If a match is found, the matching item is forwarded to output port
1
and the iteration ends.
If the match is not found, a new Item
is generated at
storage 1
with a matching attribute value and forwarded
to output port 1
.
See the Code to Generate the Custom Storage Block with Multiple
Storages
Discrete state variable InputKey
represents the
recorded reference value from Order
, which is used to
select corresponding Item
.
properties (DiscreteState)
InputKey;
end
The block has two storages with FIFO behavior. Storage
1
supports entities with type
Item
, and storage 2
supports entities
with type Order
. The block has two input ports and one
output port. Input port 1
and output port
1
are connected to storage 1
.
Input port 2
is connected to storage
2
. For more information about declaring ports and
storages, see Implement a Discrete-Event System Object with MATLAB Discrete-Event System Block.
function num = getNumInputsImpl(~) num = 2; end function num = getNumOutputsImpl(~) num = 1; end function [entityTypes] = getEntityTypesImpl(obj) entityTypes = [obj.entityType('Item'), ... obj.entityType('Order')]; end function [inputTypes, outputTypes] = getEntityPortsImpl(~) inputTypes = {'Item' 'Order'}; outputTypes = {'Order'}; end function [storageSpecs, I, O] = getEntityStorageImpl(obj) storageSpecs = [obj.queueFIFO('Item', obj.capacity)... obj.queueFIFO('Order', obj.capacity)]; I = [1 2]; O = 1; end
Specify the discrete state and reset the state
InputKey
. For more information about states in
discrete-event systems, see Custom Entity Generator Block with Signal Input and Signal Output.
function [sz, dt, cp] = getDiscreteStateSpecificationImpl(obj, name) sz = 1; dt = 'double'; cp = false; end function resetImpl(obj) obj.InputKey = 0; end
When Order
arrives at storage 2, its data
Key
is recorded in the discrete state variable
Obj.InputKey
. This entry also invokes an iteration
event at storage 1
and another event to destroy
Order
.
function [Order, events] = OrderEntry(obj, storage, Order, source) % A key entity has arrived; record the Inputkey value. obj.InputKey = Order.data.Key; % Schedule an iteration of the entities in storage 1. % Destroy input key entity. events = [obj.eventIterate(1, '') ... obj.eventDestroy()]; coder.extrinsic('fprintf'); fprintf('Order Key Value: %f\n', Order.data.Key); end
The purpose of the iteration is to find items with data that matches
InputKey
.
function [Item,events,continueIter] = ItemIterate(obj,... storage, Item, tag, cur) % Find entities with matching key. events = obj.initEventArray; continueIter = true; if (Item.data.Attribute1 == obj.InputKey) events = obj.eventForward('output', 1, 0.0); % If a match is found, the iteration ends and the state is reset. continueIter = false; elseif cur.size == cur.position % If a match is not found, this invokes an entity generation event. events = obj.eventGenerate(1,'mygen',0.0,100); end end
Generate an entity with type entity1
and a matching
Key
value. Then, forward the generated entity to
output port 1
.
function [Item,events] = ItemGenerate(obj,storage,Item,tag) % Specify event actions when entity generated in the storage. Item.data.Attribute1 = obj.InputKey; events = obj.eventForward('output',1,0.0); end
Save the .m
file as
CustomBlockTwoEntityStorages
. Link the System object to a SimEvents® model using a MATLAB Discrete-Event
System block. For more information about linking, see Create Custom Blocks Using MATLAB Discrete-Event System Block.
Create a SimEvents model including the MATLAB Discrete-Event System block, two Entity Generator blocks, and an Entity Terminator block. Connect the blocks as shown in the model.
In the Entity Generator block:
In the Entity generation tab, set the
Generate entity at simulation start to
off
.
In the Entity type tab, set the
Entity type name as
Item
.
In the Event Actions tab, in the Generate action field enter:
entity.Attribute1 = randi([1 3]);
By default, the entities are generated with intergeneration time
1
and their Attribute1
value is a random integer between 1
and
3
.
In the Statistics tab, output the Number of entities departed, d statistic and connect it to a scope.
In the Entity Generator1 block:
In the Entity generation tab, set
Generate entity at simulation start to
off
, and set Period to
5
.
In the Entity type tab, set the
Entity type name as
Order
and Attribute Name
as Key
.
In the Event Actions tab, in the Generate action field enter:
entity.Key = randi([1 4]);
Entities with type Order
are generated with
intergeneration time 5
, and the Key
attribute takes integer values between 1
and
4
.
There is no possible match between Key
and
Attribute1
when the Key
value is
4
because Attribute1
can take the
value 1
, 2
, or
3
.
In the Entity Terminator block, output the Number of entities arrived, a statistic and connect it to a scope.
Right-click the entity path from the MATLAB Discrete-Event System block to the Entity Terminator block and select Log Selected Signals.
Increase simulation time to 50
and simulate the model.
Observe that:
50
entities with type
Entity1
enter storage 1 in the
block.
In the Diagnostic Viewer, observe the incoming
Key
reference values carried by
10
entities that enter storage 2 and are
destroyed afterward.
The Simulation Data Inspector shows the departing items and
their Attribute1
values. The values match the
Key
values displayed in the Diagnostic
Viewer.
Also observe 5
entities departing with
Attribute1
value 4
.
These entities are generated in storage 2 because
Attribute1
cannot have the value
4
for the entities generated by the
Entity Generator block.
entry
| generate
| getEntityPortsImpl
| getEntityStorageImpl
| iterate
| matlab.DiscreteEventSystem
| matlab.System