build a custom block with multiple storages
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 methods. to
observe the behavior of the custom block, see .
create the discrete-event system object
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 typeitem
to storage1
.input port
2
accepts reference entities with typeorder
to storage2
.when a reference
order
arrives at storage2
, its attribute data is recorded as the reference value, and the entity is destroyed.the
order
arrival invokes an iteration event at storage1
to search for anitem
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 storage1
with a matching attribute value and forwarded to output port1
.
custom block behavior
discrete state variable
inputkey
represents the recorded reference value fromorder
, which is used to select correspondingitem
.properties (discretestate) inputkey; end
the block has two storages with fifo behavior. storage
1
supports entities with typeitem
, and storage2
supports entities with typeorder
. the block has two input ports and one output port. input port1
and output port1
are connected to storage1
. input port2
is connected to storage2
. for more information about declaring ports and storages, see .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 .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 datakey
is recorded in the discrete state variableobj.inputkey
. this entry also invokes an iteration event at storage1
and another event to destroyorder
.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 matchingkey
value. then, forward the generated entity to output port1
.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
implement the custom block
save the
.m
file ascustomblocktwoentitystorages
. link the system object to a simevents® model using a block. for more information about linking, see .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 theirattribute1
value is a random integer between1
and3
.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 to5
.in the entity type tab, set the entity type name as
order
and attribute name askey
.in the event actions tab, in the generate action field enter:
entity.key = randi([1 4]);
entities with type
order
are generated with intergeneration time5
, and thekey
attribute takes integer values between1
and4
.there is no possible match between
key
andattribute1
when thekey
value is4
becauseattribute1
can take the value1
,2
, or3
.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 typeentity1
enter storage 1 in the block.in the diagnostic viewer, observe the incoming
key
reference values carried by10
entities that enter storage 2 and are destroyed afterward.the simulation data inspector shows the departing items and their
attribute1
values. the values match thekey
values displayed in the diagnostic viewer.also observe
5
entities departing withattribute1
value4
. these entities are generated in storage 2 becauseattribute1
cannot have the value4
for the entities generated by the entity generator block.
see also
| | | | | |