Main Content

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 matlab.DiscreteEventSystem methods. To observe the behavior of the custom block, see CustomEntityStorageBlockWithTwoStoragesExample.

Create the Discrete-Event System Object

Generate a custom entity storage block with two inputs, one output, and two storage elements.

Graphical representation of a Discrete-Event system showing a rectangle with two input ports and one output port containing two storage elements, Storage 1 and Storage 2. Storage 2 points to Storage 1 through an arrow looping upwards labeled "Iterate". Storage 1 is connected to the single output port.

The desired behavior of the custom block is to select and output entities based on a reference entity.

  1. Input port 1 accepts entities with type Item to storage 1.

  2. Input port 2 accepts reference entities with type Order to storage 2.

  3. When a reference Order arrives at storage 2, its attribute data is recorded as the reference value, and the entity is destroyed.

  4. The Order arrival invokes an iteration event at storage 1 to search for an Item carrying data that is equal to the reference value.

  5. If a match is found, the matching item is forwarded to output port 1 and the iteration ends.

  6. 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

Custom Block Behavior

  1. Discrete state variable InputKey represents the recorded reference value from Order, which is used to select corresponding Item.

        properties (DiscreteState)
            InputKey;
        end
  2. 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
  3. 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
  4. 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
  5. 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

  6. 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

Implement the Custom Block

  1. 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.

  2. 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.

    Block diagram showing two Entity Generator blocks, Entity Generator and Entity Generator1 connected to a MATLAB Discrete-Event System with System Object name CustomBlockTwoEntityStorages. The output signal from the MATLAB Discrete-Event System block is connected to an Entity Terminator block that, in turn, connects to a Scope block named Scope1. The input of Entity Generator is also connected to a Scope block.

  3. In the Entity Generator block:

    1. In the Entity generation tab, set the Generate entity at simulation start to off.

    2. In the Entity type tab, set the Entity type name as Item.

    3. 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.

    4. In the Statistics tab, output the Number of entities departed, d statistic and connect it to a scope.

  4. In the Entity Generator1 block:

    1. In the Entity generation tab, set Generate entity at simulation start to off, and set Period to 5.

    2. In the Entity type tab, set the Entity type name as Order and Attribute Name as Key.

    3. 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.

  5. In the Entity Terminator block, output the Number of entities arrived, a statistic and connect it to a scope.

  6. Right-click the entity path from the MATLAB Discrete-Event System block to the Entity Terminator block and select Log Selected Signals.

  7. Increase simulation time to 50 and simulate the model. Observe that:

    1. 50 entities with type Entity1 enter storage 1 in the block.

      Scope block representing the number of entities arriving at the Entity Generator block, graphically.

    2. In the Diagnostic Viewer, observe the incoming Key reference values carried by 10 entities that enter storage 2 and are destroyed afterward.

      Diagnostic Viewer screen showing the Order Key value of ten entities in written form. In order, the values are: 4.000000, 4.000000, 1.000000, 4.000000, 3.000000, 1.000000, 2.000000, 3.000000, 4.000000, 4.000000.

    3. The Simulation Data Inspector shows the departing items and their Attribute1 values. The values match the Key values displayed in the Diagnostic Viewer.

      The Simulink Data Inspector window showing the departing entities along with Attribute1 values, graphically.

      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.

See Also

| | | | | |

Related Topics